<!DOCTYPE html>
<html lang="zh" dir="ltr">

<head prefix="og: http://ogp.me/ns#">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>JavaSE 学习笔记 – Vigilr的博客</title>
    


<script src="/js/enquire.min.aa37bdcb743826eecdae5c5d177fc7d6552340f1b4378ffaa9c82b2c6111400b.js"></script>

<script defer src="/js/lazysizes.min.5e11d056075a05065b9c0bfec44084a113fc2976c2952ec804dedb61c7662db9.js"></script>

<script defer src="/js/fuse.min.c4bee9a8d44273d6154fe86006923d4131eb2e8069d8897687137c6f37f553e3.js"></script>

<script defer src="/js/helper/getParents.min.1618c696be7c98933f9a92677f518b512a74e55bdbb976b09936b4182e93181b.js"></script>

<script defer src="/js/helper/fadeinout.min.93a331f96194789a542f33690bbe4f0c102c7e78ffc018217f5a1c33010bad91.js"></script>

<script defer src="/js/helper/closest.min.js"></script>
  
<script>
  "use strict";

  
  
  if (window.NodeList && !NodeList.prototype.forEach) {
    NodeList.prototype.forEach = Array.prototype.forEach;
  }

  
  if (!String.prototype.includes) {
    String.prototype.includes = function (search, start) {
      'use strict';

      if (search instanceof RegExp) {
        throw TypeError('first argument must not be a RegExp');
      }
      if (start === undefined) { start = 0; }
      return this.indexOf(search, start) !== -1;
    };
  }

  
  Document.prototype.append = Element.prototype.append = function append() {
    this.appendChild(_mutation(arguments));
  };
  function _mutation(nodes) {
    if (!nodes.length) {
      throw new Error('DOM Exception 8');
    } else if (nodes.length === 1) {
      return typeof nodes[0] === 'string' ? document.createTextNode(nodes[0]) : nodes[0];
    } else {
      var
      fragment = document.createDocumentFragment(),
      length = nodes.length,
      index = -1,
      node;

      while (++index < length) {
        node = nodes[index];

        fragment.appendChild(typeof node === 'string' ? document.createTextNode(node) : node);
      }

      return fragment;
    }
  }

  
  if (!String.prototype.startsWith) {
    String.prototype.startsWith = function (searchString, position) {
      position = position || 0;
      return this.indexOf(searchString, position) === position;
    };
  }
  


  document.addEventListener('DOMContentLoaded', function () {
    
    var navCollapseBtn = document.querySelector('.navbar__burger');
    navCollapseBtn ? navCollapseBtn.addEventListener('click', function (e) {
      var navCollapse = document.querySelector('.navbarm__collapse');

      if (navCollapse) {
        var dataOpen = navCollapse.getAttribute('data-open');

        if (dataOpen === 'true') {
          navCollapse.setAttribute('data-open', 'false');
          navCollapse.style.maxHeight = 0;
          navCollapseBtn.classList.remove('is-active');
        } else {
          navCollapse.setAttribute('data-open', 'true');
          navCollapse.style.maxHeight = navCollapse.scrollHeight + "px";
          navCollapseBtn.classList.add('is-active');
        }
      }
    }) : null;
    


    
    var summaryContainer = document.querySelector('.summary__container');
    var searchResult = document.querySelector('.search-result');
    var searchResultCloseBtn = document.querySelector('.search-result__close');
    searchResultCloseBtn ? searchResultCloseBtn.addEventListener('click', function (e) {
      searchResult.setAttribute('data-display', 'none');
      summaryContainer.setAttribute('data-display', 'block');
    }) : null;
    


    
    document.querySelectorAll('.tab') ? 
    document.querySelectorAll('.tab').forEach(function(elem, idx) {
      var containerId = elem.getAttribute('id');
      var containerElem = elem;
      var tabLinks = elem.querySelectorAll('.tab__link');
      var tabContents = elem.querySelectorAll('.tab__content');
      var ids = [];

      tabLinks && tabLinks.length > 0 ?
      tabLinks.forEach(function(link, index, self) {
        link.onclick = function(e) {
          for (var i = 0; i < self.length; i++) {
            if (index === parseInt(i, 10)) {
              if (!self[i].classList.contains('active')) {
                self[i].classList.add('active');
                tabContents[i].style.display = 'block';
              }
            } else {
              self[i].classList.remove('active');
              tabContents[i].style.display = 'none';
            }
          }
        }
      }) : null;
    }) : null;
    


    
    document.querySelectorAll('.codetab') ? 
    document.querySelectorAll('.codetab').forEach(function(elem, idx) {
      var containerId = elem.getAttribute('id');
      var containerElem = elem;
      var codetabLinks = elem.querySelectorAll('.codetab__link');
      var codetabContents = elem.querySelectorAll('.codetab__content');
      var ids = [];

      codetabLinks && codetabLinks.length > 0 ?
      codetabLinks.forEach(function(link, index, self) {
        link.onclick = function(e) {
          for (var i = 0; i < self.length; i++) {
            if (index === parseInt(i, 10)) {
              if (!self[i].classList.contains('active')) {
                self[i].classList.add('active');
                codetabContents[i].style.display = 'block';
              }
            } else {
              self[i].classList.remove('active');
              codetabContents[i].style.display = 'none';
            }
          }
        }
      }) : null;
    }) : null;
    


    
    var gttBtn = document.getElementById("gtt");
    gttBtn.style.display = "none";
    gttBtn.addEventListener('click', function () {
      if (window.document.documentMode) {
        document.documentElement.scrollTop = 0;
      } else {
        scrollToTop(250);
      }
    });

    function scrollToTop(scrollDuration) {
      var scrollStep = -window.scrollY / (scrollDuration / 15);
      var scrollInterval = setInterval(function () {
        if (window.scrollY != 0) {
          window.scrollBy(0, scrollStep);
        }
        else clearInterval(scrollInterval);
      }, 15);
    }

    var scrollFunction = function () {
      if (document.body.scrollTop > 250 || document.documentElement.scrollTop > 250) {
        gttBtn.style.display = "block";
      } else {
        gttBtn.style.display = "none";
      }
    }
    


    
    var expandBtn = document.querySelectorAll('.expand__button');

    for (let i = 0; i < expandBtn.length; i++) {
      expandBtn[i].addEventListener("click", function () {
        var content = this.nextElementSibling;
        if (content.style.maxHeight) {
          content.style.maxHeight = null;
          this.querySelector('svg').classList.add('expand-icon__right');
          this.querySelector('svg').classList.remove('expand-icon__down');
        } else {
          content.style.maxHeight = content.scrollHeight + "px";
          this.querySelector('svg').classList.remove('expand-icon__right');
          this.querySelector('svg').classList.add('expand-icon__down');
        }
      });
    }
    


    
    var lastScrollTop = window.pageYOffset || document.documentElement.scrollTop;
    var tocElem = document.querySelector('.toc');
    var tableOfContentsElem = tocElem ? tocElem.querySelector('#TableOfContents') : null;
    var toggleTocElem = document.getElementById('toggle-toc');
    var singleContentsElem = document.querySelector('.single__contents');
    var navbar = document.querySelector('.navbar');
    var tocFlexbox = document.querySelector('.toc__flexbox');
    var tocFlexboxOuter = document.querySelector('.toc__flexbox--outer');
    var expandContents = document.querySelectorAll('.expand__content');
    var boxContents = document.querySelectorAll('.box');
    var notAllowedTitleIds = null;

    
    var tocFolding = JSON.parse("true");
    
    var tocLevels = JSON.parse("[\"h2\",\"h3\",\"h4\"]");
    
    if (tocLevels) {
      tocLevels = tocLevels.toString();
    } else {
      tocLevels = "h1, h2, h3, h4, h5, h6";
    }

    
    singleContentsElem && singleContentsElem.querySelectorAll(".tab") ?
    singleContentsElem.querySelectorAll(".tab").forEach(function (elem) {
      elem.querySelectorAll(tocLevels).forEach(function (element) {
        notAllowedTitleIds = Array.isArray(notAllowedTitleIds) ?
          notAllowedTitleIds.concat(element.getAttribute('id')) :
          [element.getAttribute('id')];
      });
    }) : null;

    
    expandContents ? expandContents.forEach(function(elem) {
      elem.querySelectorAll(tocLevels).forEach(function (element) {
        notAllowedTitleIds = Array.isArray(notAllowedTitleIds) ?
          notAllowedTitleIds.concat(element.getAttribute('id')) :
          [element.getAttribute('id')];
      });
    }) : null;

    
    boxContents ? boxContents.forEach(function(elem) {
      elem.querySelectorAll(tocLevels).forEach(function (element) {
        notAllowedTitleIds = Array.isArray(notAllowedTitleIds) ?
          notAllowedTitleIds.concat(element.getAttribute('id')) :
          [element.getAttribute('id')];
      });
    }) : null;

    
    window.onscroll = function () {
      scrollFunction();
      
      var st = window.pageYOffset || document.documentElement.scrollTop;
      if (st > lastScrollTop) { 
        if (st < 250) {
          gttBtn.style.display = "none";
        } else {
          gttBtn.style.display = "block";
        }

        if (st < 45) {
          return null;
        }
        
        if (!navbar.classList.contains('navbar--hide')) {
          navbar.classList.add('navbar--hide');
        } else if (navbar.classList.contains('navbar--show')) {
          navbar.classList.remove('navbar--show');
        }

        if (singleContentsElem) {
          if (singleContentsElem.querySelectorAll(tocLevels).length > 0) {
            singleContentsElem.querySelectorAll(tocLevels).forEach(function (elem) {
              if (toggleTocElem && !toggleTocElem.checked) {
                return null;
              }

              if (notAllowedTitleIds && notAllowedTitleIds.includes(elem.getAttribute('id'))) {
                return null;
              }
              
              if (document.documentElement.scrollTop >= elem.offsetTop) {
                if (tableOfContentsElem) {
                  var id = elem.getAttribute('id');
                  tocElem.querySelectorAll('a').forEach(function (elem) {
                    elem.classList.remove('active');
                  });
                  tocElem.querySelector('a[href="#' + id + '"]') ?
                    tocElem.querySelector('a[href="#' + id + '"]').classList.add('active') : null;

                  if (false === tocFolding) {
                    
                  } else {
                    tableOfContentsElem.querySelectorAll('ul') ?
                      tableOfContentsElem.querySelectorAll('ul').forEach(function (rootUl) {
                        rootUl.querySelectorAll('li').forEach(function (liElem) {
                          liElem.querySelectorAll('ul').forEach(function (ulElem) {
                            ulElem.style.display = 'none';
                          });
                        });
                      }) : null;
                  }

                  var curElem = tableOfContentsElem.querySelector("[href='#" + id + "']");
                  if (curElem && curElem.nextElementSibling) {
                    curElem.nextElementSibling.style.display = 'block';
                  }
                  getParents(curElem, 'ul') ?
                    getParents(curElem, 'ul').forEach(function (elem) {
                      elem.style.display = 'block';
                    }) : null;
                }
              }
            });
          } else {
            if (tocFlexbox) {
              tocFlexbox.setAttribute('data-position', '');
              if (!tocFlexbox.classList.contains('hide')) {
                tocFlexbox.classList.add('hide');
              }
            }
            if (tocFlexboxOuter) {
              tocFlexboxOuter.setAttribute('data-position', '');
              if (!tocFlexboxOuter.classList.contains('hide')) {
                tocFlexboxOuter.classList.add('hide');
              }
            }
          }
        }
      } else { 
        if (st < 250) {
          gttBtn.style.display = "none";
        }

        if (navbar.classList.contains('navbar--hide')) {
          navbar.classList.remove('navbar--hide');
        } else if (!navbar.classList.contains('navbar--show')) {
          navbar.classList.add('navbar--show');
        }

        if (singleContentsElem) {
          if (singleContentsElem.querySelectorAll(tocLevels).length > 0) {
            singleContentsElem.querySelectorAll(tocLevels).forEach(function (elem) {
              if (toggleTocElem && !toggleTocElem.checked) {
                return null;
              }
              
              if (notAllowedTitleIds && notAllowedTitleIds.includes(elem.getAttribute('id'))) {
                return null;
              }

              if (document.documentElement.scrollTop >= elem.offsetTop) {
                if (tableOfContentsElem) {
                  var id = elem.getAttribute('id');
                  tocElem.querySelectorAll('a').forEach(function (elem) {
                    elem.classList.remove('active');
                  });
                  tocElem.querySelector('a[href="#' + id + '"]') ?
                    tocElem.querySelector('a[href="#' + id + '"]').classList.add('active') : null;

                  if (false === tocFolding) {
                    
                  } else {
                    tableOfContentsElem.querySelectorAll('ul') ?
                      tableOfContentsElem.querySelectorAll('ul').forEach(function (rootUl) {
                        rootUl.querySelectorAll('li').forEach(function (liElem) {
                          liElem.querySelectorAll('ul').forEach(function (ulElem) {
                            ulElem.style.display = 'none';
                          });
                        });
                      }) : null;
                  }

                  var curElem = tableOfContentsElem.querySelector("[href='#" + id + "']");
                  if (curElem && curElem.nextElementSibling) {
                    curElem.nextElementSibling.style.display = 'block';
                  }
                  getParents(curElem, 'ul') ?
                    getParents(curElem, 'ul').forEach(function (elem) {
                      elem.style.display = 'block';
                    }) : null;
                }
              }
            });
          } else {
            if (tocFlexbox && !tocFlexbox.classList.contains('hide')) {
              tocFlexbox.classList.add('hide');
            }
            if (tocFlexboxOuter && !tocFlexboxOuter.classList.contains('hide')) {
              tocFlexboxOuter.classList.add('hide');
            }
          }
          
        }

        if (tableOfContentsElem && document.documentElement.scrollTop < 250) {
          if (false === tocFolding) {

          } else {
            tableOfContentsElem.querySelector('ul') ?
              tableOfContentsElem.querySelector('ul').querySelectorAll('li').forEach(function (liElem) {
                liElem.querySelectorAll('ul').forEach(function (ulElem) {
                  ulElem.style.display = 'none';
                });
              }) : null;
          }
        }
      }
      lastScrollTop = st <= 0 ? 0 : st;
    };
  


  
    var localTheme = localStorage.getItem('theme');
    var rootEleme = document.getElementById('root');
    var selectThemeElem = document.querySelectorAll('.select-theme');
    var selectThemeItemElem = document.querySelectorAll('.select-theme__item');

    var setMetaColor = function(themeColor) {
      var metaMsapplicationTileColor = document.getElementsByName('msapplication-TileColor')[0];
      var metaThemeColor = document.getElementsByName('theme-color')[0];
      var metaMsapplicationNavbuttonColor = document.getElementsByName('msapplication-navbutton-color')[0];
      var metaAppleMobileWebAappStatusBarStyle = document.getElementsByName('apple-mobile-web-app-status-bar-style')[0];

      if (themeColor.includes('dark')) {
        metaMsapplicationTileColor.setAttribute('content', '#fcfcfa');
        metaThemeColor.setAttribute('content', '#403E41');
        metaMsapplicationNavbuttonColor.setAttribute('content', '#403E41');
        metaAppleMobileWebAappStatusBarStyle.setAttribute('content', '#403E41');
      } else if (themeColor.includes('light')) {
        metaMsapplicationTileColor.setAttribute('content', '#555');
        metaThemeColor.setAttribute('content', '#eee');
        metaMsapplicationNavbuttonColor.setAttribute('content', '#eee');
        metaAppleMobileWebAappStatusBarStyle.setAttribute('content', '#eee');
      } else if (themeColor.includes('hacker')) {
        metaMsapplicationTileColor.setAttribute('content', '#e3cd26');
        metaThemeColor.setAttribute('content', '#252526');
        metaMsapplicationNavbuttonColor.setAttribute('content', '#252526');
        metaAppleMobileWebAappStatusBarStyle.setAttribute('content', '#252526');
      } else if (themeColor.includes('solarized')) {
        metaMsapplicationTileColor.setAttribute('content', '#d3af86');
        metaThemeColor.setAttribute('content', '#51412c');
        metaMsapplicationNavbuttonColor.setAttribute('content', '#51412c');
        metaAppleMobileWebAappStatusBarStyle.setAttribute('content', '#51412c');
      } else if (themeColor.includes('kimbie')) {
        metaMsapplicationTileColor.setAttribute('content', '#586e75');
        metaThemeColor.setAttribute('content', '#eee8d5');
        metaMsapplicationNavbuttonColor.setAttribute('content', '#eee8d5');
        metaAppleMobileWebAappStatusBarStyle.setAttribute('content', '#eee8d5');
      } 
    }
    
    if (localTheme) {
      selectThemeItemElem ? 
      selectThemeItemElem.forEach(function (elem) {
        if (elem.text.trim() === localTheme) {
          elem.classList.add('is-active');
        } else {
          elem.classList.remove('is-active');
        }
      }) : null;

      setMetaColor(localTheme);
    } else {
      setMetaColor(rootEleme.className);
    }

    selectThemeItemElem ? 
    selectThemeItemElem.forEach(function (v, i) {
      v.addEventListener('click', function (e) {
        var selectedThemeVariant = e.target.text.trim();
        localStorage.setItem('theme', selectedThemeVariant);
        setMetaColor(selectedThemeVariant);

        rootEleme.removeAttribute('class');
        rootEleme.classList.add('theme__' + selectedThemeVariant);
        selectThemeElem.forEach(function(rootElem) {
          rootElem.querySelectorAll('a').forEach(function (elem) {
            if (elem.classList) {
              if (elem.text.trim() === selectedThemeVariant) {
                if (!elem.classList.contains('is-active')) {
                  elem.classList.add('is-active');
                }
              } else {
                if (elem.classList.contains('is-active')) {
                  elem.classList.remove('is-active');
                }
              }
            }
          });
        });

        if (window.mermaid) {
          if (selectedThemeVariant === "solarized" || selectedThemeVariant === "hacker") {
            mermaid.initialize({ theme: 'solarized' });
            location.reload();
          } else {
            mermaid.initialize({ theme: 'default' });
            location.reload();
          }
        }

        var utterances = document.getElementById('utterances');
        if (utterances) {
          utterances.querySelector('iframe').contentWindow.postMessage({
            type: 'set-theme',
            theme: selectedThemeVariant === "dark" || selectedThemeVariant === "hacker" ? 'photon-dark' : selectedThemeVariant === 'kimbie' ? 'github-dark-orange' : 'github-light',
          }, 'https://utteranc.es');
        }

        var twitterCards = document.querySelectorAll('.twitter-timeline');
        if (twitterCards) {
          window.postMessage({
            type: 'set-twitter-theme',
            theme: selectedThemeVariant === 'light' || selectedThemeVariant === 'solarized' ? 'light' : 'dark',
          });
        }
      });
    }) : null;
  


  
    
    var permalink = JSON.parse("\"https://eternidad33.gitee.io/zh/posts/java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/\"");
    var searchResults = null;
    var searchMenu = null;
    var searchText = null;
    
    
    var enableSearchHighlight = JSON.parse("true");
    
    var searchResultPosition = JSON.parse("\"main\"");
    
    var sectionType = JSON.parse("\"posts\"");

    var fuse = null;

    (function initFuse() {
      var xhr = new XMLHttpRequest();
      xhr.open('GET', permalink + "index.json");
      xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
      xhr.onload = function () {
        if (xhr.status === 200) {
          fuse = new Fuse(JSON.parse(xhr.response.toString('utf-8')), {
            keys: sectionType.includes('publication') ? ['title', 'abstract'] : ['title', 'description', 'content'],
            includeMatches: enableSearchHighlight,
            shouldSort: true,
            threshold: 0.4,
            location: 0,
            distance: 100,
            maxPatternLength: 32,
            minMatchCharLength: 1,
          });
          window.fuse = fuse;
        }
        else {
          console.error('[' + xhr.status + ']Error:', xhr.statusText);
        }
      };
      xhr.send();
    })();

    function makeLi(ulElem, obj) {
      var li = document.createElement('li');
      li.className = 'search-result__item';
      
      var a = document.createElement('a');
      a.innerHTML = obj.title;
      a.setAttribute('class', 'search-result__item--title');
      a.setAttribute('href', obj.permalink);

      var descDiv = document.createElement('div');
      descDiv.setAttribute('class', 'search-result__item--desc');
      if (obj.description) {
        descDiv.innerHTML = obj.description;
      } else if (obj.content) {
        descDiv.innerHTML = obj.content.substring(0, 225);
      }
      
      li.appendChild(a);
      li.appendChild(descDiv);
      ulElem.appendChild(li);
    }

    function makeHighlightLi(ulElem, obj) {
      var li = document.createElement('li');
      li.className = 'search-result__item';
      var descDiv = null;

      var a = document.createElement('a');
      a.innerHTML = obj.item.title;
      a.setAttribute('class', 'search-result__item--title');
      a.setAttribute('href', obj.item.uri);

      if (obj.matches && obj.matches.length) {
        for (var i = 0; i < obj.matches.length; i++) {
          if ('title' === obj.matches[i].key) {
            a = document.createElement('a');
            a.innerHTML = generateHighlightedText(obj.matches[i].value, obj.matches[i].indices);
            a.setAttribute('class', 'search-result__item--title');
            a.setAttribute('href', obj.item.uri);
          }
          
          if ('description' === obj.matches[i].key) {
            descDiv = document.createElement('div');
            descDiv.setAttribute('class', 'search-result__item--desc');
            descDiv.innerHTML = generateHighlightedText(obj.item.description, obj.matches[i].indices);
          } else if ('content' === obj.matches[i].key) {
            if (!descDiv) {
              descDiv = document.createElement('div');
              descDiv.setAttribute('class', 'search-result__item--desc');
              descDiv.innerHTML = generateHighlightedText(obj.item.content.substring(0, 150), obj.matches[i].indices);
            }
          } else {
            if (obj.item.description) {
              descDiv = document.createElement('div');
              descDiv.setAttribute('class', 'search-result__item--desc');
              descDiv.innerHTML = obj.item.description;
            } else {
              descDiv = document.createElement('div');
              descDiv.setAttribute('class', 'search-result__item--desc');
              descDiv.innerHTML = obj.item.content.substring(0, 150);
            }
          }
        }

        li.appendChild(a);
        if (descDiv) {
          li.appendChild(descDiv);
        }
        if (li) {
          ulElem.appendChild(li);
        }
      }
    }

    function renderSearchResultsSide(searchText, results) {
      searchResults = document.getElementById('search-results');
      searchMenu = document.getElementById('search-menu');
      searchResults.setAttribute('class', 'dropdown is-active');
      
      var ul = document.createElement('ul');
      ul.setAttribute('class', 'dropdown-content search-content');

      if (results.length) {
        results.forEach(function (result) {
          var li = document.createElement('li');
          var a = document.createElement('a');
          a.setAttribute('href', result.uri);
          a.setAttribute('class', 'dropdown-item');
          a.appendChild(li);

          var titleDiv = document.createElement('div');
          titleDiv.innerHTML = result.title;
          titleDiv.setAttribute('class', 'menu-item__title');

          var descDiv = document.createElement('div');
          descDiv.setAttribute('class', 'menu-item__desc');
          if (result.description) {
            descDiv.innerHTML = result.description;
          } else if (result.content) {
            descDiv.innerHTML = result.content.substring(0, 150);
          }

          li.appendChild(titleDiv);
          li.appendChild(descDiv);
          ul.appendChild(a);
        });
      } else {
        var li = document.createElement('li');
        li.setAttribute('class', 'dropdown-item');
        li.innerText = 'No results found';
        ul.appendChild(li);
      }

      while (searchMenu.hasChildNodes()) {
        searchMenu.removeChild(
          searchMenu.lastChild
        );
      }
      
      searchMenu.appendChild(ul);
    }

    function renderSearchHighlightResultsSide(searchText, results) {
      searchResults = document.getElementById('search-results');
      searchMenu = document.getElementById('search-menu');
      searchResults.setAttribute('class', 'dropdown is-active');

      var ul = document.createElement('ul');
      ul.setAttribute('class', 'dropdown-content search-content');

      if (results.length) {
        results.forEach(function (result) {
          var li = document.createElement('li');
          var a = document.createElement('a');
          var descDiv = null;

          a.setAttribute('href', result.item.uri);
          a.setAttribute('class', 'dropdown-item');
          a.appendChild(li);

          var titleDiv = document.createElement('div');
          titleDiv.innerHTML = result.item.title;
          titleDiv.setAttribute('class', 'menu-item__title');
          
          if (result.matches && result.matches.length) {
            for (var i = 0; i < result.matches.length; i++) {
              if ('title' === result.matches[i].key) {
                titleDiv.innerHTML = generateHighlightedText(result.matches[i].value, result.matches[i].indices);
              }

              if ('description' === result.matches[i].key) {
                descDiv = document.createElement('div');
                descDiv.setAttribute('class', 'menu-item__desc');
                descDiv.innerHTML = generateHighlightedText(result.item.description, result.matches[i].indices);
              } else if ('content' === result.matches[i].key) {
                if (!descDiv) {
                  descDiv = document.createElement('div');
                  descDiv.setAttribute('class', 'menu-item__desc');
                  descDiv.innerHTML = generateHighlightedText(result.item.content.substring(0, 150), result.matches[i].indices);
                }
              } else {
                if (result.item.description) {
                  descDiv = document.createElement('div');
                  descDiv.setAttribute('class', 'menu-item__desc');
                  descDiv.innerHTML = result.item.description;
                } else {
                  descDiv = document.createElement('div');
                  descDiv.setAttribute('class', 'menu-item__desc');
                  descDiv.innerHTML = result.item.content.substring(0, 150);
                }
              }
            }
            
            li.appendChild(titleDiv);
            if (descDiv) {
              li.appendChild(descDiv);
            }
            ul.appendChild(a);
          }
        });
      } else {
        var li = document.createElement('li');
        li.setAttribute('class', 'dropdown-item');
        li.innerText = 'No results found';
        ul.appendChild(li);
      }

      while (searchMenu.hasChildNodes()) {
        searchMenu.removeChild(
          searchMenu.lastChild
        );
      }
      searchMenu.appendChild(ul);
    }

    function renderSearchResultsMobile(searchText, results) {
      searchResults = document.getElementById('search-mobile-results');

      var content = document.createElement('div');
      content.setAttribute('class', 'mobile-search__content');

      if (results.length > 0) {
        results.forEach(function (result) {
          var item = document.createElement('a');
          item.setAttribute('href', result.uri);
          item.innerHTML = '<div class="mobile-search__item"><div class="mobile-search__item--title">📄 ' + result.title + '</div><div class="mobile-search__item--desc">' + (result.description ? result.description : result.content) + '</div></div>';
          content.appendChild(item);
        });
      } else {
        var item = document.createElement('span');
        content.appendChild(item);
      }

      let wrap = document.getElementById('search-mobile-results');
      while (wrap.firstChild) {
        wrap.removeChild(wrap.firstChild)
      }
      searchResults.appendChild(content);      
    }

    function renderSearchHighlightResultsMobile(searchText, results) {
      searchResults = document.getElementById('search-mobile-results');

      var ul = document.createElement('div');
      ul.setAttribute('class', 'mobile-search__content');

      if (results.length) {
        results.forEach(function (result) {
          var li = document.createElement('li');
          var a = document.createElement('a');
          var descDiv = null;

          a.setAttribute('href', result.item.uri);
          a.appendChild(li);
          li.setAttribute('class', 'mobile-search__item');

          var titleDiv = document.createElement('div');
          titleDiv.innerHTML = result.item.title;
          titleDiv.setAttribute('class', 'mobile-search__item--title');
          
          if (result.matches && result.matches.length) {
            for (var i = 0; i < result.matches.length; i++) {
              if ('title' === result.matches[i].key) {
                titleDiv.innerHTML = generateHighlightedText(result.matches[i].value, result.matches[i].indices);
              }

              if ('description' === result.matches[i].key) {
                descDiv = document.createElement('div');
                descDiv.setAttribute('class', 'mobile-search__item--desc');
                descDiv.innerHTML = generateHighlightedText(result.item.description, result.matches[i].indices);
              } else if ('content' === result.matches[i].key) {
                if (!descDiv) {
                  descDiv = document.createElement('div');
                  descDiv.setAttribute('class', 'mobile-search__item--desc');
                  descDiv.innerHTML = generateHighlightedText(result.item.content.substring(0, 150), result.matches[i].indices);
                }
              } else {
                if (result.item.description) {
                  descDiv = document.createElement('div');
                  descDiv.setAttribute('class', 'mobile-search__item--desc');
                  descDiv.innerHTML = result.item.description;
                } else {
                  descDiv = document.createElement('div');
                  descDiv.setAttribute('class', 'mobile-search__item--desc');
                  descDiv.innerHTML = result.item.content.substring(0, 150);
                }
              }
            }
            
            li.appendChild(titleDiv);
            if (descDiv) {
              li.appendChild(descDiv);
            }
            ul.appendChild(a);
          }
        });
      } else {
        var item = document.createElement('span');
        ul.appendChild(item);
      }

      let wrap = document.getElementById('search-mobile-results');
      while (wrap.firstChild) {
        wrap.removeChild(wrap.firstChild)
      }
      searchResults.appendChild(ul);
    }

    function generateHighlightedText(text, regions) {
      if (!regions) {
        return text;
      }

      var content = '', nextUnhighlightedRegionStartingIndex = 0;

      regions.forEach(function(region) {
        if (region[0] === region[1]) {
          return null;
        }
        
        content += '' +
          text.substring(nextUnhighlightedRegionStartingIndex, region[0]) +
          '<span class="search__highlight">' +
            text.substring(region[0], region[1] + 1) +
          '</span>' +
        '';
        nextUnhighlightedRegionStartingIndex = region[1] + 1;
      });

      content += text.substring(nextUnhighlightedRegionStartingIndex);

      return content;
    };

    var searchElem = document.getElementById('search');
    var searchMobile = document.getElementById('search-mobile');
    var searchResultsContainer = document.getElementById('search-results');

    searchElem ?
    searchElem.addEventListener('input', function(e) {
      if (!e.target.value | window.innerWidth < 770) {
        searchResultsContainer ? searchResultsContainer.setAttribute('class', 'dropdown') : null;
        searchResult ? searchResult.setAttribute('data-display', 'none') : null;
        summaryContainer ? summaryContainer.setAttribute('data-display', 'block') : null;
        return null;
      }

      searchText = e.target.value;
      var results = fuse.search(e.target.value);
      
      if (searchResultPosition === "main") {
        if (enableSearchHighlight) {
          renderSearchHighlightResultsMain(searchText, results);
        } else {
          renderSearchResultsMain(searchText, results);
        }
      } else {
        if (enableSearchHighlight) {
          renderSearchHighlightResultsSide(searchText, results);
        } else {
          renderSearchResultsSide(searchText, results);
        }
        
        var dropdownItems = searchResultsContainer.querySelectorAll('.dropdown-item');
        dropdownItems ? dropdownItems.forEach(function(item) {
          item.addEventListener('mousedown', function(e) {
            e.target.click();
          });
        }) : null;
      }
    }) : null;

    searchElem ? 
    searchElem.addEventListener('blur', function() {
      if (window.innerWidth < 770) {
        return null;
      }
      searchResultsContainer ? searchResultsContainer.setAttribute('class', 'dropdown') : null;
    }) : null;

    searchElem ? 
    searchElem.addEventListener('click', function(e) {
      if (window.innerWidth < 770) {
        return null;
      }
      if (!e.target.value) {
        searchResultsContainer ? searchResultsContainer.setAttribute('class', 'dropdown') : null;
        return null;
      }

      searchText = e.target.value;
      var results = fuse.search(e.target.value);

      if (searchResultPosition === "main") {
        if (enableSearchHighlight) {
          renderSearchHighlightResultsMain(searchText, results);
        } else {
          renderSearchResultsMain(searchText, results);
        }
      } else{
        if (enableSearchHighlight) {
          renderSearchHighlightResultsSide(searchText, results);
        } else {
          renderSearchResultsSide(searchText, results);
        }

        var dropdownItems = searchResultsContainer.querySelectorAll('.dropdown-item');
        dropdownItems ? dropdownItems.forEach(function (item) {
          item.addEventListener('mousedown', function (e) {
            e.target.click();
          });
        }) : null;
      }
    }) : null;

    var searchMenuElem = document.getElementById("search-menu");
    var activeItem = document.querySelector('#search-menu .dropdown-item.is-active');
    var activeIndex = null;
    var items = null;
    var searchContainerMaxHeight = 350;

    searchElem ? 
    searchElem.addEventListener('keydown', function(e) {
      if (window.innerWidth < 770) {
        return null;
      }

      if (e.key === 'Escape') {
        searchResult ? searchResult.setAttribute('data-display', 'none') : null;
        summaryContainer ? summaryContainer.setAttribute('data-display', 'block') : null;
      }

      var items = document.querySelectorAll('#search-menu .dropdown-item');
      var keyCode = e.which || e.keyCode;

      if (!items || !items.length) {
        return null;
      }
      
      if (e.key === 'ArrowDown' || keyCode === 40) {
        if (activeIndex === null) {
          activeIndex = 0;
          items[activeIndex].classList.remove('is-active');
        } else {
          items[activeIndex].classList.remove('is-active');
          activeIndex = activeIndex === items.length - 1 ? 0 : activeIndex + 1;
        }
        items[activeIndex].classList.add('is-active');

        let overflowedPixel = items[activeIndex].offsetTop + items[activeIndex].clientHeight - searchContainerMaxHeight;
        if (overflowedPixel > 0) {
          document.querySelector(".search-content").scrollTop += items[activeIndex].getBoundingClientRect().height;
        } else if (activeIndex === 0) {
          document.querySelector(".search-content").scrollTop = 0;
        }
      } else if (e.key === 'ArrowUp' || keyCode === 38) {
        if (activeIndex === null) {
          activeIndex = items.length - 1;
          items[activeIndex].classList.remove('is-active');
        } else {
          items[activeIndex].classList.remove('is-active');
          activeIndex = activeIndex === 0 ? items.length - 1 : activeIndex - 1;
        }
        items[activeIndex].classList.add('is-active');
        
        let overflowedPixel = items[activeIndex].offsetTop + items[activeIndex].clientHeight - searchContainerMaxHeight;
        if (overflowedPixel < 0) {
          document.querySelector(".search-content").scrollTop -= items[activeIndex].getBoundingClientRect().height;
        } else {
          document.querySelector(".search-content").scrollTop = overflowedPixel + items[activeIndex].getBoundingClientRect().height;
        }
      } else if (e.key === 'Enter' || keyCode === 13) {
        if (items[activeIndex] && items[activeIndex].getAttribute('href')) {
          location.href = items[activeIndex].getAttribute('href');
        }
      } else if (e.key === 'Escape' || keyCode === 27) {
        e.target.value = null;
        if (searchResults) {
          searchResults.classList.remove('is-active');
        }
      }
    }) : null;

    searchMobile ? 
    searchMobile.addEventListener('input', function(e) {
      if (!e.target.value) {
        let wrap = document.getElementById('search-mobile-results');
        while (wrap.firstChild) {
          wrap.removeChild(wrap.firstChild);
        }
        return null;
      }

      searchText = e.target.value;
      var results = fuse.search(e.target.value);
      renderSearchResultsMobile(searchText, results);
      if (enableSearchHighlight) {
        renderSearchHighlightResultsMobile(searchText, results);
      } else {
        renderSearchResultsMobile(searchText, results);
      }
    }) : null;
  


  
    var mobileSearchInputElem = document.querySelector('#search-mobile');
    var mobileSearchClassElem = document.querySelector('.mobile-search');
    var mobileSearchBtnElem = document.querySelector('#mobileSearchBtn');
    var mobileSearchCloseBtnElem = document.querySelector('#search-mobile-close');
    var mobileSearchContainer = document.querySelector('#search-mobile-container');
    var mobileSearchResultsElem = document.querySelector('#search-mobile-results');
    var htmlElem = document.querySelector('html');

    if (mobileSearchClassElem) {
      mobileSearchClassElem.style.display = 'none';
    }

    mobileSearchBtnElem ? 
    mobileSearchBtnElem.addEventListener('click', function () {
      if (mobileSearchContainer) {
        mobileSearchContainer.style.display = 'block';
      }

      if (mobileSearchInputElem) {
        mobileSearchInputElem.focus();
      }

      if (htmlElem) {
        htmlElem.style.overflowY = 'hidden';
      }
    }) : null;

    mobileSearchCloseBtnElem ? 
    mobileSearchCloseBtnElem.addEventListener('click', function() {
      if (mobileSearchContainer) {
        mobileSearchContainer.style.display = 'none';
      }

      if (mobileSearchInputElem) {
        mobileSearchInputElem.value = '';
      }
      
      if (mobileSearchResultsElem) {
        while (mobileSearchResultsElem.firstChild) {
          mobileSearchResultsElem.removeChild(mobileSearchResultsElem.firstChild);
        }
      }

      if (htmlElem) {
        htmlElem.style.overflowY = 'visible';
      }
    }) : null;

    mobileSearchInputElem ?
    mobileSearchInputElem.addEventListener('keydown', function(e) {
      var keyCode = e.which || e.keyCode;
      if (e.key === 'Escape' || keyCode === 27) {
        if (mobileSearchContainer) {
          mobileSearchContainer.style.display = 'none';
        }
        
        if (mobileSearchInputElem) {
          mobileSearchInputElem.value = '';
        }

        if (mobileSearchResultsElem) {
          while (mobileSearchResultsElem.firstChild) {
            mobileSearchResultsElem.removeChild(mobileSearchResultsElem.firstChild);
          }
        }
        if (htmlElem) {
          htmlElem.style.overflowY = 'visible';
        }
      }
    }) : null;
  


  
    function renderSearchResultsMain(searchText, results) {
      var searchBody = document.querySelector('.search-result__body');
      var originUl = searchBody.querySelector('ul');
      var ul = document.createElement('ul');
      
      if (!searchText) {
        searchResult ? searchResult.setAttribute('data-display', 'none') : null;
        summaryContainer ? summaryContainer.setAttribute('data-display', 'block') : null;
      } else if (results) {
        if (results && results.length) {
          results.forEach(function (result) {
            makeLi(ul, result);
          });

          searchResult ? searchResult.setAttribute('data-display', 'block') : null;
          summaryContainer ? summaryContainer.setAttribute('data-display', 'none') : null;
        }
      }

      originUl.parentNode.replaceChild(ul, originUl);
    }

    function renderSearchHighlightResultsMain(searchText, results) {
      var searchBody = document.querySelector('.search-result__body');
      var originUl = searchBody.querySelector('ul');
      var ul = document.createElement('ul');

      if (!searchText) {
        searchResult ? searchResult.setAttribute('data-display', 'none') : null;
        summaryContainer ? summaryContainer.setAttribute('data-display', 'block') : null;
      } else if (results) {
        if (results && results.length) {
          results.forEach(function (result) {
            makeHighlightLi(ul, result);
          });

          searchResult ? searchResult.setAttribute('data-display', 'block') : null;
          summaryContainer ? summaryContainer.setAttribute('data-display', 'none') : null;
        }
      }

      originUl.parentNode.replaceChild(ul, originUl);
    }
  
  });
</script>    
    


<link rel="stylesheet" href="/css/main.min.css">


    
<meta name="description" content="The Zzo theme for Hugo example site." />


<meta name="keywords" content="java">

<meta name="created" content="2020-04-10T00:00:00&#43;0000">
<meta name="modified" content="2020-04-10T00:00:00&#43;0000">
<meta property="article:published_time" content="2020-04-10T00:00:00&#43;0000">

<meta name="author" content="Vigilr">


<meta property="og:site_name" content="Vigilr的博客">
<meta property="og:title" content="JavaSE 学习笔记">
<meta property="og:url" content="https://eternidad33.gitee.io/zh/posts/java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/">
<meta property="og:type" content="article">
<meta property="og:description" content="The Zzo theme for Hugo example site.">

<meta name="generator" content="Hugo 0.69.0" />
<meta name="msapplication-TileColor" content="#fff">

<meta name="theme-color" content="#fff">

<meta name="msapplication-navbutton-color" content="#fff">

<meta name="apple-mobile-web-app-status-bar-style" content="#fff">

<link rel="canonical" href="https://eternidad33.gitee.io/zh/posts/java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/">

<link rel="manifest" href="/manifest.json">

  <link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-icon-57x57.png">
  <link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-icon-60x60.png">
  <link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-icon-72x72.png">
  <link rel="apple-touch-icon" sizes="76x76" href="/favicon/apple-icon-76x76.png">
  <link rel="apple-touch-icon" sizes="114x114" href="/favicon/apple-icon-114x114.png">
  <link rel="apple-touch-icon" sizes="120x120" href="/favicon/apple-icon-120x120.png">
  <link rel="apple-touch-icon" sizes="144x144" href="/favicon/apple-icon-144x144.png">
  <link rel="apple-touch-icon" sizes="152x152" href="/favicon/apple-icon-152x152.png">
  <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-icon-180x180.png">
  <link rel="icon" type="image/png" sizes="192x192" href="/favicon/android-icon-192x192.png">
  <link rel="icon" type="image/png" sizes="192x192" href="/favicon/android-icon-512x512.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
  <link rel="icon" type="image/png" sizes="96x96" href="/favicon/favicon-96x96.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
  <meta name="msapplication-TileColor" content="#ffffff">
  <meta name="msapplication-TileImage" content="/ms-icon-144x144.png">


    <script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@type": "WebPage",
    "headline": "JavaSE 学习笔记",
    "datePublished": "2020-04-10T00:00:00Z",
    "dateModified": "2020-04-10T00:00:00Z",
    "url" : "https://eternidad33.gitee.io/zh/posts/java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/",
    "description": "推荐书籍： 《Java 编程的逻辑》 《疯狂 Java 讲义精粹》 Java 基础 从当前所在路径加载类SET ClASSPATH=. PATH：是操作系统提供的路径配置，定义所有可执行程序的",
    "keywords": ["java"],
    "mainEntityOfPage": {
      "@type": "WebPage",
      "@id": "https://eternidad33.gitee.io/"
    },
    "publisher": {
      "@type": "Organization",
      "name": "Vigilr的博客",
      "url": "https://eternidad33.gitee.io/"
    }
  }
</script>

    
  
  







    
</head>

<body id="root" class="theme__dark">
    <script>
        var localTheme = localStorage.getItem('theme');
        if (localTheme) {
            document.getElementById('root').className = 'theme__' + localTheme;
        }
    </script>
    <div id="container">
        





        <div class="wrapper" data-type="posts" data-kind="page">
            <nav class="navbar" role="navigation" aria-label="main navigation" data-dir="ltr">
  <div class="navbar__brand">
    
    <a href="/zh/" title="主页" rel="home" class="navbar__logo-link">
      <img src="/logo.png" alt="Home" class="navbar__logo">
    </a>
    
    
      <a href="/zh/" title="主页" rel="home" class="navbar__title-link">
        <h6 class="navbar__title">Vigilr</h6>
      </a>
    
  </div>

  
<div class="theme theme-mobile" data-ani="true">
  <div class="dropdown">
    <button class="dropdown-trigger navbar__slide-down" aria-label="Select Theme Button" style="" data-ani="true">
      <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24"><path fill="none" d="M24 0H0v24h24V0z"/><path fill="currentColor" d="M6.34 7.93c-3.12 3.12-3.12 8.19 0 11.31C7.9 20.8 9.95 21.58 12 21.58s4.1-.78 5.66-2.34c3.12-3.12 3.12-8.19 0-11.31l-4.95-4.95c-.39-.39-1.02-.39-1.41 0L6.34 7.93zM12 19.59c-1.6 0-3.11-.62-4.24-1.76C6.62 16.69 6 15.19 6 13.59s.62-3.11 1.76-4.24L12 5.1v14.49z"/></svg>      
    </button>
    <div class="dropdown-content select-theme">
      
        
        <a href="#" class="dropdown-item select-theme__item is-active">
          dark
        </a>
        
        <a href="#" class="dropdown-item select-theme__item ">
          light
        </a>
        
        <a href="#" class="dropdown-item select-theme__item ">
          hacker
        </a>
        
        <a href="#" class="dropdown-item select-theme__item ">
          solarized
        </a>
        
        <a href="#" class="dropdown-item select-theme__item ">
          kimbie
        </a>
        
      
    </div>
  </div>
</div>


<div id="mobileSearchBtn" class="mobile-search__btn" data-ani="true">
  <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="currentColor" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M15.5 14h-.79l-.28-.27c1.2-1.4 1.82-3.31 1.48-5.34-.47-2.78-2.79-5-5.59-5.34-4.23-.52-7.79 3.04-7.27 7.27.34 2.8 2.56 5.12 5.34 5.59 2.03.34 3.94-.28 5.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>
</div>

<div id="search-mobile-container" class="mobile-search hide" data-dir="ltr">
  <div class="mobile-search__top">
    <input id="search-mobile" type="text" aria-label="Mobile Search" placeholder="搜索" class="mobile-search__top--input"/>
    <div id="search-mobile-close" class="mobile-search__top--icon">
      <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24"><path opacity=".87" fill="none" d="M0 0h24v24H0V0z"/><path fill="currentColor" d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm3.59-13L12 10.59 8.41 7 7 8.41 10.59 12 7 15.59 8.41 17 12 13.41 15.59 17 17 15.59 13.41 12 17 8.41z"/></svg>
    </div>
  </div>
  <div id="search-mobile-results" class="mobile-search__body">
    
  </div>
</div>


<a role="button" class="navbar__burger" aria-label="menu" aria-expanded="false"
  data-ani="true">
  <span aria-hidden="true"></span>
  <span aria-hidden="true"></span>
  <span aria-hidden="true"></span>
</a>
<div class="navbarm__collapse" data-open="false">
  <ul dir="ltr">
    
    
      
      
      
      

      
        <li class="navbarm__menu--item ">
          <a href="/zh/about">关于</a>
        </li>
      
      
    
      
      
      
      

      
        <li class="navbarm__menu--item ">
          <a href="/zh/archive">归档</a>
        </li>
      
      
    
      
      
      
      

      
        <li class="navbarm__menu--item active">
          <a href="/zh/posts">文章</a>
        </li>
      
      
    

    
      <li class="navbarm__menu--item ">
        <a href="/zh/tags" class="navbarm__menu--term" data-index="0">
          标签
        </a>
      </li>
    
      <li class="navbarm__menu--item ">
        <a href="/zh/categories" class="navbarm__menu--term" data-index="1">
          分类
        </a>
      </li>
    
      <li class="navbarm__menu--item ">
        <a href="/zh/series" class="navbarm__menu--term" data-index="2">
          文集
        </a>
      </li>
    
  </ul>
</div>
  <div class="navbar__menu">
  
<div class="theme" data-ani="true">
  <div class="dropdown">
    <button class="dropdown-trigger navbar__slide-down" aria-label="Select Theme Button" data-ani="true">
      <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24"><path fill="none" d="M24 0H0v24h24V0z"/><path fill="currentColor" d="M6.34 7.93c-3.12 3.12-3.12 8.19 0 11.31C7.9 20.8 9.95 21.58 12 21.58s4.1-.78 5.66-2.34c3.12-3.12 3.12-8.19 0-11.31l-4.95-4.95c-.39-.39-1.02-.39-1.41 0L6.34 7.93zM12 19.59c-1.6 0-3.11-.62-4.24-1.76C6.62 16.69 6 15.19 6 13.59s.62-3.11 1.76-4.24L12 5.1v14.49z"/></svg>      
    </button>
    <div class="dropdown-content select-theme">
      
        
        <a href="#" class="dropdown-item select-theme__item is-active">
          dark
        </a>
        
        <a href="#" class="dropdown-item select-theme__item ">
          light
        </a>
        
        <a href="#" class="dropdown-item select-theme__item ">
          hacker
        </a>
        
        <a href="#" class="dropdown-item select-theme__item ">
          solarized
        </a>
        
        <a href="#" class="dropdown-item select-theme__item ">
          kimbie
        </a>
        
      
    </div>
  </div>
</div>

  
  
  
  
  
  
  
  <a href="/zh/about" class="navbar__menu-item navbar__slide-down " dir="ltr" data-ani="true">关于</a>
  
  
  
  
  
  
  
  <a href="/zh/archive" class="navbar__menu-item navbar__slide-down " dir="ltr" data-ani="true">归档</a>
  
  
  
  
  
  
  
  <a href="/zh/posts" class="navbar__menu-item navbar__slide-down active" dir="ltr" data-ani="true">文章</a>
  
  
</div>
</nav>
            
            

<main class="single__main main-main">
  
    <nav class="breadcrumb hide" aria-label="breadcrumbs">
  <script>document.querySelector('.breadcrumb').classList.remove('hide')</script>
  <ol>
    
  
  
  
  
  
  <li >
    
      <a href="https://eternidad33.gitee.io/zh/" class="capitalize">Vigilr的博客</a>
    
  </li>
  
  
  <li >
    
      <a href="https://eternidad33.gitee.io/zh/posts/" class="capitalize">最新文章</a>
    
  </li>
  
  
  <li  class="is-active" >
    
      <span>JavaSE 学习笔记</span>
    
  </li>
  
  </ol>
  
</nav>
  
  
  <div class="single ">
    <div class="single__nojs">Please enable Javascript to view the contents</div>
    <script>document.querySelector('.single').classList.remove('hide'); document.querySelector('.single__nojs').classList.add('hide');</script>
    <h2 class="single__title" data-ani="true">JavaSE 学习笔记</h2>
    <div class="single__meta">
      
<div class="single__infos">
  <time class="single__info" title="创建日期">📅&nbsp;2020年04月10日 </time>
  
  &nbsp;&middot;&nbsp; <span class="single__info" title="阅读时长"> ☕&nbsp;32&nbsp;分钟 </span>
  
  <span class="single__info">
    
  </span>
</div>
      
<ul class="single__tags caption">
  
  🏷️
  

  <li><a href="https://eternidad33.gitee.io/zh/tags/java/" class="single__tag" title="java">#java</a></li>

</ul>
    </div>
    <article class="single__contents" data-dir="ltr" data-ani="true">
      
<div class="expand">
  <button type="button" class="expand__button" aria-label="Expand Button">
    <span class="expand-icon expand-icon__right">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M9.29 15.88L13.17 12 9.29 8.12c-.39-.39-.39-1.02 0-1.41.39-.39 1.02-.39 1.41 0l4.59 4.59c.39.39.39 1.02 0 1.41L10.7 17.3c-.39.39-1.02.39-1.41 0-.38-.39-.39-1.03 0-1.42z"/></svg>
    </span>
    目录
  </button>
  <div class="expand__content expand__content--toc">
    <nav id="TableOfContents">
  <ul>
    <li>
      <ul>
        <li><a href="#java-基础">Java 基础</a></li>
        <li><a href="#数组">数组</a></li>
        <li><a href="#string">String</a></li>
        <li><a href="#面向对象">面向对象</a>
          <ul>
            <li><a href="#继承">继承</a></li>
            <li><a href="#多态">多态</a></li>
            <li><a href="#object-类">Object 类</a></li>
            <li><a href="#抽象类">抽象类</a></li>
            <li><a href="#包装类">包装类</a></li>
            <li><a href="#接口">接口</a></li>
          </ul>
        </li>
        <li><a href="#设计模式">设计模式</a></li>
        <li><a href="#泛型">泛型</a></li>
        <li><a href="#包">包</a></li>
        <li><a href="#uml">UML</a></li>
        <li><a href="#枚举">枚举</a></li>
        <li><a href="#异常">异常</a></li>
        <li><a href="#内部类">内部类</a></li>
        <li><a href="#函数式编程">函数式编程</a></li>
        <li><a href="#链表">链表</a></li>
        <li><a href="#awt">AWT</a></li>
        <li><a href="#正则表达式">正则表达式</a></li>
        <li><a href="#list-集合">List 集合</a></li>
        <li><a href="#set-集合">Set 集合</a></li>
        <li><a href="#map-集合">Map 集合</a></li>
        <li><a href="#java-多线程编程">Java 多线程编程</a>
          <ul>
            <li><a href="#thread-与-runnable-关系">Thread 与 Runnable 关系</a></li>
            <li><a href="#线程常用操作方法">线程常用操作方法</a></li>
            <li><a href="#线程的同步与死锁">线程的同步与死锁</a></li>
          </ul>
        </li>
        <li><a href="#基础类库">基础类库</a></li>
        <li><a href="#比较器">比较器</a></li>
        <li><a href="#红黑树原理">红黑树原理</a></li>
        <li><a href="#文件操作">文件操作</a></li>
        <li><a href="#字节流与字符流">字节流与字符流</a></li>
        <li><a href="#io-操作深入">IO 操作深入</a></li>
        <li><a href="#输入与输出支持">输入与输出支持</a></li>
        <li><a href="#对象序列化">对象序列化</a></li>
        <li><a href="#反射机制">反射机制</a></li>
        <li><a href="#集合工具类">集合工具类</a></li>
        <li><a href="#stream-数据流">Stream 数据流</a></li>
        <li><a href="#网络编程">网络编程</a></li>
        <li><a href="#jdbc">JDBC</a></li>
      </ul>
    </li>
  </ul>
</nav>
  </div>
</div>

      <p>推荐书籍：</p>
<ul>
<li><a href="https://weread.qq.com/web/reader/b51320f05e159eb51b29226kc81322c012c81e728d9d180">《Java 编程的逻辑》</a></li>
<li><a href="https://weread.qq.com/web/reader/b9f325405a64efb9fa69ebfkc81322c012c81e728d9d180">《疯狂 Java 讲义精粹》</a></li>
</ul>
<h3 id="java-基础">Java 基础</h3>
<p>从当前所在路径加载类<code>SET ClASSPATH=.</code></p>
<p>PATH：是操作系统提供的路径配置，定义所有可执行程序的路径</p>
<p>CLASSPATH：是由 JRE 提供的，用于定义 Java 程序解释时类加载路径<code>CLASSPATH=路径</code>的命令形式来进行定义；</p>
<p>Java 1.9 之后才有的<code>Jshell</code></p>
<p><code>int</code>的取值范围为-2147483648 到 2147483647</p>
<p>大写字母范围：A(65)~Z(90)</p>
<p>小写字母范围：a(97)~z(122)</p>
<p>数值范围：&lsquo;0&rsquo;(48)~'9&rsquo;(57)</p>
<p><strong>this</strong>关键字</p>
<p><strong>this()</strong>:调用无参的构造函数</p>
<p><strong>this(name)</strong>:调用参数为 name 的构造函数</p>
<p><strong>this(&hellip;)</strong>:必须放在首行</p>
<p>Static 属性由类名直接调用</p>
<p>static 方法只允许调用 static 属性或 static 方法</p>
<p>非 static 方法允许调用 static 属性或 static 方法</p>
<p>static 的定义的方法或属性都不是代码编写之初所需要考虑的内容，只有在回避实例化对象描述公共属性的情况下才会考虑 static 定义的属性或者是方法</p>
<p>静态代码块<em>最先执行</em>，而且只会执行一次，用于对静态属性的初始化，构造块会优于构造方法先执行</p>
<h3 id="数组">数组</h3>
<p><code>int</code>数组初始化默认为 0</p>
<p>必须实例化数组才能使用数组下标</p>
<p><code>foreach</code>循环可以避免使用下标，</p>
<p><code>foreach</code>遍历二维数组</p>
<p>返回数组的方法</p>
<p>将数组封装成一个组件</p>
<p>数组快速排序</p>
<p>数组逆序</p>
<p>数组相关的类库</p>
<p>数组排序可以这样写<code>java.util.Arrays.sort(data);</code></p>
<p>系统自带的数组拷贝<code>System.arraycopy(dataA,5,dataB,5,3);</code>是将数组<code>dataA</code>中从索引为 5，长度为 3 的一段数组复制到<code>dataB</code>中索引位置为 5 的地方，并替换掉相应长度</p>
<p>可变参数</p>
<p>在方法参数列表中<code>...</code>表示可变参数</p>
<p>可变参数的作用在于，在以后进行一些程序设计或者开发者调用的时候，利用此种形式可以避免数组的传递操作</p>
<p>对象数组定义格式如下：</p>
<ul>
<li>动态初始化：类 对象数组名称[]=new 类[长度]，每一个元素的内容都是 null</li>
<li>静态初始化：类 对象数组名称[]=new 类[]{实例化对象，实例化对象，实例化对象&hellip;}</li>
</ul>
<h3 id="string">String</h3>
<p>java 源代码目录:<code>C:\Program Files (x86)\Java\jdk-9\lib\src.zip</code></p>
<p>JDK 1.8 及以前的 String 支持类</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/java1.8String.png" alt="java1.8" /></p>
<p>JDK 1.9 的 String 支持类</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/java1.9string.png" alt="java1.9" /></p>
<p>JDK 1.8 及以前 String 类保存的是字符数组</p>
<p>JDK 1.9 及以后 String 类保存的是字节数组</p>
<p><strong><em>String 对象的比较</em></strong></p>
<p>直接为字符串赋值会是字符串变量指向字符串池中的内存地址</p>
<p><code>new String()</code>会开辟新的内存</p>
<p>将所有小写字母转换成大写</p>
<p>先将字符串转换成字符数组，然后每个字符的编码-32</p>
<p><strong>判断是否全为数字</strong></p>
<p>先将字符串转换成字符数组，<code>if (result[i] &lt; '0' || result[i] &gt; '9')</code></p>
<p>然后挨个判断每个字符</p>
<p><strong>字符串的比较</strong></p>
<p><code>str.equals(str1)</code>区分大小写比较</p>
<p><code>str.equalsIgnoreCase(str1)</code>不区分大小写比较</p>
<p><code>str.compareTo(str1)</code>字符串的大小的比较</p>
<p><code>str.compareToIgnoreCase(str1)</code>忽略大小写的字符串大小比较</p>
<p><strong>字符串的查找</strong></p>
<p><code>str.contains(&quot;hello&quot;)</code>判断字符串中是否含有 hello</p>
<p><code>str.indexOf(&quot;Java&quot;)</code>查询 Java 是否存在于 str 中，存在返回首字母索引位置，不存在返回-1</p>
<p><code>str.lastIndexOf(&quot;Java&quot;)</code>从后向前查询</p>
<p><code>str2.endsWith(&quot;com&quot;)</code>判断是否以 com 结尾</p>
<p><code>str2.startsWith(&quot;www&quot;)</code>判断是否以 www 开头</p>
<p><strong>字符串的替换</strong></p>
<p><code>str.replaceAll(&quot;Java&quot;, &quot;Python&quot;)</code>将全部的 Java 替换成 Python</p>
<p><code>str.replaceFirst(&quot;Java&quot;, &quot;Python&quot;)</code>将第一个 Java 替换成 Python</p>
<p><strong>字符串的拆分</strong></p>
<p><code>str.split(&quot; &quot;)</code>以空格全部拆分，返回字符串数组</p>
<p><code>str.split(&quot; &quot;,2)</code>以空格拆分成 2 个，返回字符串数组</p>
<p><code>str1.split(&quot;\\.&quot;)</code>拆不开的情况要用&rdquo;\&ldquo;进行转义</p>
<p><strong>字符串的截取</strong></p>
<p><code>str.substring(startIndex,endIndex)</code>截取<code>str</code>从<code>startIndex</code>到<code>endIndex</code>的字符串片段</p>
<p><strong>字符串的格式化</strong></p>
<p>format 是一个静态方法,直接通过<strong>String 类调用</strong><code>String.format(&quot;姓名：%s，年龄：%d，分数：%5.2f&quot;,name,age,score</code>)</p>
<p><strong>其他字符串相关的方法</strong></p>
<p><code>str.concat(str2)</code>字符串的连接</p>
<p><code>str.isEmpty()</code>判断字符串内容是否为空</p>
<p><code>str.trim()</code>去掉字符串中所有空格</p>
<p><code>str.toUpperCase()</code>全部转换成大写</p>
<p><code>(str.toLowerCase()</code>全部转换成小写</p>
<h3 id="面向对象">面向对象</h3>
<h4 id="继承">继承</h4>
<p><code>public class object.Student extends object.Person</code>Student 类继承 Person 所有共有的属性和方法</p>
<p>子类被实例化时先调用父类的构造方法</p>
<p><code>super(...)</code>必须放在首行，<code>this(...)</code>也必须放在首行，所以两者不可同时出现</p>
<p><strong>多层继承</strong></p>
<p>理论上层数最多不能超过三层</p>
<ul>
<li>父类的私有方法不存在覆写</li>
<li>子类调用有父类覆写的方法要加 super</li>
</ul>
<table>
<thead>
<tr>
<th align="center">Overloading</th>
<th align="center">Override</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">重载</td>
<td align="center">覆写</td>
</tr>
<tr>
<td align="center">方法名称相同，参数的类型及个数不同</td>
<td align="center">方法名称，参数类型及个数，返回值相同</td>
</tr>
<tr>
<td align="center">没有权限限制</td>
<td align="center">被覆写方法不能拥有更严格的控制权限</td>
</tr>
<tr>
<td align="center">发生在一个类中</td>
<td align="center">发生在继承关系类中</td>
</tr>
</tbody>
</table>
<blockquote>
<p>在程序类中使用 this 表示先从本类查找所需要的的属性或方法，如果本类中不存在则查找父类定义，如果使用 super 则不查找子类，直接查找父类</p>
</blockquote>
<p>fanal 代表不能被覆写的方法，常量</p>
<p><strong>Annotation 注解</strong></p>
<p><code>@Override</code>准确覆写</p>
<p><code>@Deprecated</code> 代表过时的类或方法</p>
<p><code>@SuppressWarnings</code> 压制警告</p>
<h4 id="多态">多态</h4>
<p>向上转型<code>base f = new son()</code>可以调用父类的方法和子类中重写父类的方法</p>
<p>向下转型<code>son1 s=(son)f</code>不安全</p>
<p><code>instanceof</code></p>
<p><code>instanceof</code>为了保证向下转型的正确性，用于在转型之前进行判断，判断某个实例是否是某个类的对象</p>
<h4 id="object-类">Object 类</h4>
<p>Object 类是所有类型的父类，所以 Object 类可以接收所有子类的对象</p>
<p><code>toString()</code>是 Object 自带的方法，所有继承类都可以使用</p>
<ol>
<li>对象比较 equals()</li>
<li>判断对象是否为 null</li>
<li>判断是不是同一地址</li>
<li>判断 obj 是否转换为 person</li>
<li>判断内容是否相同</li>
</ol>
<h4 id="抽象类">抽象类</h4>
<p>抽象方法所在的类必须为抽象类，抽象类必须用<code>abstract</code>关键字来定义</p>
<p>抽象类就是在普通类上追加了抽象方法</p>
<p>抽象类是无法被实例化的</p>
<ol>
<li>抽象类必须提供子类</li>
<li>抽象类的子类（非抽象类）一定要覆写抽象类中的全部抽象方法</li>
<li>抽象类的对象实例化可以通过子类向上转型的方式完成</li>
</ol>
<blockquote>
<p>抽象类自己无法直接实例化</p>
</blockquote>
<p><code>final</code>不允许有子类，<code>abstract</code>必须有子类</p>
<blockquote>
<p>抽象类中可以使用普通方法调用抽象方法</p>
</blockquote>
<h4 id="包装类">包装类</h4>
<p><code>Int temp = new Int(10);</code>装箱，将基本数据类型保存在包装类中</p>
<p><code>int x = temp.intValue();</code>拆箱，从包装类中获取基本数据类型</p>
<ol>
<li>对象型的包装类，<code>Boolen,Character</code></li>
<li>数值型的包装类,<code>Byte,Short,Integer,Long,Float,Double</code></li>
</ol>
<p>基本的装箱与拆箱操作</p>
<p>jdk1.5 之后可以实现自动装箱与拆箱操作，包装类可以直接参与数学运算</p>
<h4 id="接口">接口</h4>
<p>接口的组成以抽象方法和全局常量为主，使用关键字<code>interface</code>定义，接口的名称通常首字母加上<code>I</code></p>
<ol>
<li>接口需要被子类实现，关键字<code>implements</code>，一个子类可以实现多个接口</li>
<li>子类（非抽象类）必须覆写接口中的全部抽象方法</li>
<li>接口对象可以通过子类对象的向上转型实例化</li>
</ol>
<p>接口的主要目的是一个子类可以实现多个接口</p>
<p>接口不允许继承父类</p>
<blockquote>
<p>Object 类对象可以接收所有的数据类型，包括基本数据类型，类对象，接口对象，数组…</p>
<p>方法不写访问权限也是<code>public</code>，不是<code>default</code></p>
</blockquote>
<p>接口可以通过<code>extends</code>集成多个父接口</p>
<p>接口的使用：</p>
<ol>
<li>进行标准设置</li>
<li>表示一种操作的能力</li>
<li>暴露远程方法视图</li>
</ol>
<p>JDK1.8 之前，在进行设计时，一般子类不直接继承接口，中间加一个过渡抽象类</p>
<p>接口的方法加上<code>public default</code>代表普通方法</p>
<h3 id="设计模式">设计模式</h3>
<p><strong>代理设计模式</strong></p>
<p>一个接口提供两个子类，其中一个是真实业务操作类，另一个是代理业务操作类</p>
<p><strong>接口与抽象类的比较</strong></p>
<table>
<thead>
<tr>
<th align="center">接口</th>
<th align="center">抽象类</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">interface 接口名称{}</td>
<td align="center">abstract class 抽象类名称{}</td>
</tr>
<tr>
<td align="center">抽象方法，全局常量，普通方法，静态方法</td>
<td align="center">构造，普通方法，静态方法，全局变量，成员</td>
</tr>
<tr>
<td align="center">只有 public 权限</td>
<td align="center">可以使用各类权限</td>
</tr>
<tr>
<td align="center">子类通过<code>implements</code>关键字可以继承多个接口</td>
<td align="center">子类通过<code>extends</code>关键字继承一个抽象类</td>
</tr>
<tr>
<td align="center">接口不允许结成抽象类，可以继承多个父接口</td>
<td align="center">抽象类可以实现若干个接口</td>
</tr>
</tbody>
</table>
<p>使用时的共同点</p>
<ol>
<li>抽象类或接口必须定义子类</li>
<li>子类必须覆写抽象类或接口的全部抽象方法</li>
<li>通过子类的向上转型实现抽象类或接口的对象实例化</li>
</ol>
<p><strong>单例设计</strong></p>
<p><strong>懒汉式</strong></p>
<p>在第一次使用时进行实例化处理</p>
<p><strong>饿汉式</strong></p>
<p>在系统加载类时，实例化对象</p>
<p><strong>多例设计</strong></p>
<p>单例设计是指只保留一个实例化对象，多例设计是指保留多个实例化对象<br />
单例设计和多例设计的本质是相同的，一定都会在内部提供有<code>static</code>方法以返回实例化对象。都要进行构造方法私有化</p>
<h3 id="泛型">泛型</h3>
<p>基本数据类型 → 包装类型 →<code>Object</code>类</p>
<p>向上转型成<code>Object</code>类，容易出现<code>ClassCastException</code>异常</p>
<blockquote>
<ol>
<li>泛型之中只允许设置引用类型，如果要操作基本类型必须使用包装类</li>
<li>泛型对象实例化对象可以简化为<code>Point&lt;Integer&gt; p1=new Point&lt;&gt;();</code></li>
</ol>
</blockquote>
<p>通配符<code>&lt;?&gt;</code>可以使泛型对象在方法中不被改变</p>
<p><code>&lt;T extends 类&gt;</code>:设置泛型的上限</p>
<p><code>&lt;T super 类&gt;</code>:设置泛型的下限</p>
<p><strong>泛型接口</strong></p>
<p>子类实现泛型接口两种方式：</p>
<ol>
<li>
<p>在子类之中继续设置泛型定义</p>
</li>
<li>
<p>子类实现父接口是直接定义泛型类型</p>
</li>
</ol>
<p><strong>泛型方法</strong></p>
<p>泛型方法不一定出现在泛型类之中</p>
<p>工厂模式中使用泛型方法</p>
<h3 id="包">包</h3>
<p>同一个目录下不能有同名的程序文件，要创建不同的目录，不同的的目录就是不同的包</p>
<p><code>javac -d . hello.java</code></p>
<p><code>-d</code>:表示要生成目录，目录为<code>package</code>定义的结构</p>
<p><code>.</code>:表示从当前目录开始生成</p>
<p>类的名称：<code>包.类名称</code></p>
<p><code>import util.Message;</code>导入其他包的类</p>
<p>当导入的几个包中出现重名的类时，定义类要用完整的类名称<code>Message msg=new util.Message();</code>。</p>
<p><strong>静态导入</strong></p>
<p><code>import static util.Math.*;</code>静态导入后可以直接使用<code>util.Math</code>中的方法</p>
<p><strong>Jar</strong></p>
<p>想用<code>javac</code>编译，然后用<code>jar</code>打包</p>
<p><code>jar -cvf &quot;名称.jar&quot; 文件夹</code></p>
<p><code>-c</code>创建一个新的<code>jar</code>文件</p>
<p><code>-v</code>得到一个详细输出</p>
<p><code>-f</code>设置生成的<code>Jar</code>文件名称</p>
<p><strong>系统常见包</strong></p>
<p><code>java.lang</code>包括 String，Number，Object 等</p>
<p><code>java.lang.reflect</code>反射机制处理包</p>
<p><code>java.util</code>工具类的定义，包括数据结构的定义</p>
<p><code>java.io</code>进行输入与输出流操作的包</p>
<p><code>java.net</code>网络程序开发的程序包</p>
<p><code>java.sql</code>进行数据库编程的开发包</p>
<p><code>java.awt</code>和<code>java.swing</code>Java 的图形界面开发包，awt 是重量级的组件，swing 是轻量级的组件</p>
<p><strong>访问控制权限</strong></p>
<p>面向对象的三个主要特点：封装，继承，多态</p>
<table>
<thead>
<tr>
<th align="center">访问范围</th>
<th align="center">private</th>
<th align="center">default</th>
<th align="center">protected</th>
<th align="center">public</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">同一包中的同一类</td>
<td align="center">√</td>
<td align="center">√</td>
<td align="center">√</td>
<td align="center">√</td>
</tr>
<tr>
<td align="center">同一包中的不同类</td>
<td align="center"></td>
<td align="center">√</td>
<td align="center">√</td>
<td align="center">√</td>
</tr>
<tr>
<td align="center">不同包的子类</td>
<td align="center"></td>
<td align="center"></td>
<td align="center">√</td>
<td align="center">√</td>
</tr>
<tr>
<td align="center">不同包的所有类</td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center">√</td>
</tr>
</tbody>
</table>
<h3 id="uml">UML</h3>
<p>UML 是统一的建模语言，本质是利用图形化的形式来实现程序类关系的描述</p>
<p><strong>类图</strong></p>
<p>类一般用三层结构来显示</p>
<table>
<thead>
<tr>
<th align="center"><strong>类名称</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">属性</td>
</tr>
<tr>
<td align="center">方法</td>
</tr>
</tbody>
</table>
<p>抽象类一般用斜体表示，也可以加上<code>abstract</code></p>
<p>属性的格式为<code>访问权限 属性名称：属性类型</code></p>
<p>访问权限的表示符为 public(<code>+</code>),private(<code>-</code>),protected(<code>#</code>)</p>
<p>方法的格式为<code>访问权限 方法名称():返回值</code>结构</p>
<p>子类实现接口用&quot;三角和虚线&rdquo;,类的继承用&quot;三角和实线&rdquo;,由子类指向父类</p>
<p><strong>时序图</strong></p>
<p>时序图用于描述代码的执行流程</p>
<p><strong>用例图</strong></p>
<p>用例图用于描述程序的执行分配</p>
<h3 id="枚举">枚举</h3>
<p>枚举主要作用于定义有限个数对象的一种结构（多例设计），通过<code>enum</code>定义枚举类</p>
<p>遍历枚举</p>
<p><code>c.ordinal()</code>:c 在枚举类中的序号</p>
<p><code>c.name()</code>:c 的值</p>
<ul>
<li><code>enum</code>:是从 JDK1.5 之后提供的一个关键字，用来定义枚举类</li>
<li><code>Enum</code>：是一个抽象类，所有使用<code>enum</code>关键字定义的类，默认继承此类</li>
</ul>
<h3 id="异常">异常</h3>
<p>处理异常的三种组合：<code>try...catch</code>，<code>try...catch...finally</code>，<code>try...finally</code></p>
<p>通过<code>e.printStackTrace();</code>获取完整的异常信息</p>
<p><strong>异常处理流程</strong></p>
<ol>
<li>产生异常，自动产生异常的实例化对象</li>
<li>如果不处理异常，JVM 默认打印异常信息，然后退出程序</li>
<li>如果存在异常处理，异常实例化对象将会被<code>try</code>语句捕获</li>
<li><code>catch</code>匹配异常</li>
<li>执行<code>finally</code></li>
</ol>
<p>处理异常最大的类型是<code>Throwable</code>，有两个子类</p>
<ol>
<li><code>Error</code>:此时程序还未执行出现的错误，开发者无法处理</li>
<li><code>Exception</code>:程序中出现的异常</li>
</ol>
<p>在多个异常处理的时候要将捕获范围大的异常放在捕获范围小的异常后面</p>
<p>通过<code>throws</code>抛出异常</p>
<p><code>throw</code>手动抛出异常</p>
<p><code>throw</code>和<code>throws</code>的区别</p>
<ul>
<li><code>throw</code>是在代码块中使用的，主要是手工对异常对象的抛出</li>
<li><code>throws</code>是在方法定义上使用的，表示将此方法中可能产生的异常明确告诉给调用处，由调用处进行处理</li>
</ul>
<p><code>RuntimeException</code>是<code>Exception</code>的子类</p>
<p>常见的<code>RuntimeException</code>： <code>NullPointerException</code>，<code>ClassCastException</code>，<code>IndexOutOfBoundsException</code></p>
<h3 id="内部类">内部类</h3>
<p>内部类的优点是可以轻松地访问外部类的私有属性，缺陷是破坏了类的结构</p>
<p>内部类和外部类之间的操作不需要<code>setter</code>和<code>getter</code>，内部类实例化对象的格式<code>外部类.内部类 内部类对象=new 外部类().new 内部类;</code></p>
<p>如果<code>Inner</code>类加上<code>private</code>属性，则<code>Inner</code>无法在外部进行使用</p>
<p><code>static</code>的类和方法只能访问外部类的<code>static</code>的属性或方法.</p>
<p><code>static</code>定义的内部类并不常用，<code>static</code>定义内部接口更常用</p>
<p><strong>在方法中定义内部类</strong></p>
<p>方法中的内部类既能访问方法中的参数，又能访问外部类的私有成员属性。对于方法中参数的访问是从 JDK1.8 开始支持的。</p>
<p><strong>匿名内部类的使用</strong></p>
<blockquote>
<p>往往使用静态方法做一个内部的匿名内部类</p>
</blockquote>
<p>匿名内部类只是一个没有名字的只能够使用一次的，并且结构固定的一个子类</p>
<h3 id="函数式编程">函数式编程</h3>
<p>从 JDK1.8 开始提供有<code>Lambda</code>表达式的支持</p>
<p><code>Lambda</code>表达式使用时有一个重要的实现要求就是 SAM(Single Abstract Method)只有一个抽象方法,该接口被称为函数式接口</p>
<p>Lambda 表达式的三种格式：</p>
<ol>
<li>没有参数：<code>()-&gt;{};</code></li>
<li>有参数：<code>(参数,参数)-&gt;{};</code></li>
<li>只有一条返回语句<code>(参数,参数)-&gt;语句;</code></li>
</ol>
<p>对方法的引用</p>
<ol>
<li>
<p>引用静态方法：<code>类名称::static 方法名称;</code></p>
<p><code>IFunction&lt;String, Integer&gt; fun = String::valueOf;</code></p>
</li>
<li>
<p>引用某个实例对象的方法：<code>实例化对象::普通方法;</code></p>
<p><code>IFunction fun=&quot;hellojava&quot;::toUpperCase;</code></p>
</li>
<li>
<p>引用特定类型的方法：<code>特定类::普通方法;</code></p>
<p><code>IFunction&lt;String&gt; fun=String::compareTo;</code></p>
</li>
<li>
<p>引用构造方法：<code>类名称::new</code></p>
<p><code>IFunction&lt;Person&gt; fun=Person::new;</code></p>
</li>
</ol>
<p>在<code>java.util.funtion</code>包中可以直接使用函数式接口</p>
<ol>
<li>
<p>功能性函数式接口</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="n">Function</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span><span class="n">Boolean</span><span class="o">&gt;</span> <span class="n">fun</span><span class="o">=</span><span class="s">&#34;hellojava&#34;</span><span class="o">::</span><span class="n">startsWith</span><span class="o">;</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">fun</span><span class="o">.</span><span class="na">apply</span><span class="o">(</span><span class="s">&#34;hello&#34;</span><span class="o">));</span>
</code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>消费型函数式接口:只能进行数据的处理，没有任何的返回</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="n">Consumer</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span> <span class="n">fun</span><span class="o">=</span><span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">::</span><span class="n">println</span><span class="o">;</span>
<span class="n">fun</span><span class="o">.</span><span class="na">accept</span><span class="o">(</span><span class="s">&#34;HelloJava&#34;</span><span class="o">);</span>
</code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>供给型函数式接口</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="n">Supplier</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span> <span class="n">fun</span><span class="o">=</span><span class="s">&#34;hellojava&#34;</span><span class="o">::</span><span class="n">toUpperCase</span><span class="o">;</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">fun</span><span class="o">.</span><span class="na">get</span><span class="o">());</span>
</code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>断言型函数式接口</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="n">Predicate</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span> <span class="n">fun</span><span class="o">=</span><span class="s">&#34;hello&#34;</span><span class="o">::</span><span class="n">equals</span><span class="o">;</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">fun</span><span class="o">.</span><span class="na">test</span><span class="o">(</span><span class="s">&#34;hello&#34;</span><span class="o">));</span>
</code></pre></td></tr></table>
</div>
</div></li>
</ol>
<h3 id="链表">链表</h3>
<p>由于数组的长度是固定的，所以要引入链表</p>
<p><strong>链表节点的增加</strong></p>
<ol>
<li>判断增加的节点是否为空</li>
<li>判断根节点是否为空</li>
<li>添加节点</li>
</ol>
<p>Link 类只负责数据的操作与根节点的处理而所有后续节点的处理全部都是有 Node 类负责。</p>
<p><strong>获取链表元素的个数</strong></p>
<ol>
<li>
<p>在<code>ILink</code>接口中增加<code>size()</code>方法</p>
</li>
<li>
<p>在<code>LinkImpl</code>中重写<code>size()</code>方法</p>
</li>
<li>
<p>在<code>LinkImpl</code>中增加私有属性<code>count</code>,然后在<code>add(E e)</code>加上<code>this.count++;</code>语句</p>
</li>
</ol>
<p><strong>判断链表是否为空</strong></p>
<p>既可以判断根节点是否为空，也可以判断长度是否为 0</p>
<p><strong>返回链表数据</strong></p>
<ol>
<li>
<p>在<code>ILink</code>接口中追加<code>public Object[] toArray();</code>方法</p>
</li>
<li>
<p>在<code>LinkImpl</code>中加上两个属性</p>
</li>
<li>
<p>在<code>Node</code>中递归获取数据</p>
</li>
<li>
<p>在<code>LinkImpl</code>中重写<code>public Object[] toArray();</code>方法</p>
</li>
</ol>
<p>链表数据的返回是以数组的形式返回</p>
<p><strong>根据索引获取数据</strong></p>
<ol>
<li>
<p><code>ILink</code>加上<code>public E get(int index);</code></p>
</li>
<li>
<p>在<code>Node</code>中定义<code>public E getNode(int index)</code></p>
</li>
<li>
<p>在<code>LinkImpl</code>中重写<code>public E get(int index)</code></p>
</li>
</ol>
<p><strong>修改指定索引的数据</strong></p>
<ol>
<li>在<code>ILink</code>加上<code>public void set(int index,E value);</code></li>
<li>在<code>Node</code>中定义<code>public void setNode(int index,E value)</code></li>
<li>在<code>LinkImpl</code>中重写<code>public void set(int index, E value)</code></li>
</ol>
<p><strong>判断指定数据是否存在</strong></p>
<ol>
<li>在<code>ILink</code>加上<code>public boolean contains(E data)</code></li>
<li>在<code>Node</code>中定义<code>public boolean containsNode(E data)</code></li>
<li>在<code>LinkImpl</code>中重写<code>public boolean contains(E data)</code></li>
</ol>
<p><strong>数据删除</strong></p>
<ol>
<li>在<code>ILink</code>中加上<code>public void remove(E data)</code></li>
<li>在<code>LinkImpl</code>中判断要删除的元素是否为根节点</li>
<li>如果不是根节点，在<code>Node</code>中定义删除节点</li>
<li>在<code>LinkImpl</code>中完善<code>public void remove(E data)</code>方法</li>
</ol>
<p><strong>数据清除</strong></p>
<ol>
<li>在<code>ILink</code>中追加<code>public void clean();</code>方法</li>
<li>在<code>LinkImpl</code>中重写<code>public void clean()</code></li>
</ol>
<h3 id="awt">AWT</h3>
<blockquote>
<ul>
<li>AWT 界面组件：包括窗口、对话框、基本组件、菜单组件。</li>
<li>AWT 布局管理器：包括流式布局 FlowLayout、区域布局 BorderLayout、网格布局 GridLayout、卡片布局 CardLayout。</li>
<li>AWT 事件处理：事件授权模型、事件类型，监听器和适配器的使用。</li>
</ul>
</blockquote>
<p>AWT 的组件包括两大类：Component 和 MenuComponent，即组件与菜单栏</p>
<p>类 java.awt.Component 是许多组件类的父类，Component 类中封装了组件通用的方法和属性，如图形的组件对象、大小、显示位置、前景色和背景色、边界、可见性等。</p>
<p>一般我们要生成一个窗口，通常是用 Window 的子类 Frame 来进行实例化，而不是直接用到 Window 类</p>
<p><strong><code>Panel</code>是一个容器，放在 Frame 组件内，可以用于包装一组组件。</strong></p>
<blockquote>
<p>idea 中中文乱码设置<code>VM option: -Dfile.encoding=GB18030</code></p>
</blockquote>
<p><strong>对话框<code>Dialog</code></strong></p>
<p><strong>创建文本对话框<code>FileDialog</code></strong></p>
<p><strong><em>基本组件</em></strong></p>
<ol>
<li>文本<code>Label</code></li>
<li>按钮<code>Button</code></li>
<li>复选框<code>Checkbox</code></li>
<li>复选框组<code>CheckboxGroup</code></li>
<li>下拉列表<code>Choice</code></li>
<li>文本框<code>TextField</code></li>
<li>文本区域<code>TextArea</code></li>
<li>列表<code>List</code></li>
<li>画布<code>CAnvas</code></li>
</ol>
<p><strong><em>菜单组件</em></strong></p>
<ol>
<li>菜单栏<code>MenuBar</code></li>
<li>菜单<code>Menu</code></li>
<li>菜单选项<code>MenuItem</code></li>
</ol>
<p><strong><em>AWT 布局管理器</em></strong></p>
<blockquote>
<p>Frame 是一个顶级窗口。Frame 的默认布局管理器为<code>BorderLayout</code>。</p>
<p>Panel 无法单独显示，必须添加到某个容器中。Panel 的默认布局管理器为 FlowLayout。</p>
<p>当把 Panel 作为一个组件添加到某个容器中后，该 Panel 仍然可以有自己的布局管理器。因此，可以利用 Panel 使得<code>BorderLayout</code>中某个区域显示多个组件，达到设计复杂用户界面的目的。</p>
<p>如果采用无布局管理器<code>setLayout(null)</code>，则必须使用<code>setLocation()</code>、<code>setSize()</code>、<code>setBounds()</code>等方法手工设置组件的大小和位置，此方法会导致平台相关，不鼓励使用。</p>
</blockquote>
<p><strong>流式布局 FlowLayout</strong></p>
<p>FlowLayout 是 Panel、Applet 的默认布局管理器。其组件的放置规律是从上到下、从左到右进行放置，如果容器足够宽，第一个组件先添加到容器中第一行的最左边，后续的组件依次添加到上一个组件的右边，如果当前行已放置不下该组件，则放置到下一行的最左边。</p>
<p><code>FlowLayout(FlowLayout.RIGHT,20,40);</code>：第一个参数表示组件的对齐方式，指组件在这一行中的位置是居中对齐、居右对齐还是居左对齐，第二个参数是组件之间的横向间隔，第三个参数是组件之间的纵向间隔，单位是像素。</p>
<p><strong>区域布局 BorderLayout</strong></p>
<p>BorderLayout 是 Window、Frame 和 Dialog 的默认布局管理器。BorderLayout 布局管理器把容器分成 5 个区域：North、South、East、West 和 Center，每个区域只能放置一个组件。</p>
<blockquote>
<p>不一定所有的区域都有组件，如果四周的区域（West、East、North、South 区域）没有组件，则由 Center 区域去补充，但是如果 Center 区域没有组件，则保持空白</p>
</blockquote>
<p><strong>网格布局 GridLayout</strong></p>
<p>GridLayout 使容器中各个组件呈网格状布局，平均占据容器的空间，创建该布局时需要指定网格的行数和列数，然后依次添加各个组件时，会按照先行后列的顺序依次添加。</p>
<p><strong>卡片布局 CardLayout</strong></p>
<p>CardLayout 卡片布局管理器能够帮助用户处理两个以至更多的成员共享同一显示空间，它把容器分成许多层，每层的显示空间占据整个容器的大小，但是每层只允许放置一个组件，当然每层都可以利用 Panel 来实现复杂的用户界面。</p>
<p><strong><em>AWT 事件处理</em></strong></p>
<p>使用授权处理模型进行事件处理的一般方法归纳如下。</p>
<ul>
<li>
<p>对于某种类型的事件 XXXEvent，要想接收并处理这类事件，必须定义相应的事件监听器类，该类需要实现与该事件相对应的接口 XXXListener。</p>
</li>
<li>
<p>事件源实例化以后，必须进行授权，注册该类事件的监听器，使用 addXXXListener(XXXListener )方法来注册监听器。</p>
</li>
</ul>
<p>AWT 事件共有 10 类，可以归为两大类：低级事件和高级事件。</p>
<p>低级事件是指基于组件和容器的事件，当一个组件上发生事件，如：鼠标的进入、单击、拖放等，或组件的窗口开关等，触发了组件事件。</p>
<p>高级事件是基于语义的事件，它可以不和特定的动作相关联，而依赖于触发此事件的类，如在 TextField 中按 Enter 键会触发 ActionEvent 事件，滑动滚动条会触发 AdjustmentEvent 事件，或是选中项目列表的某一条就会触发 ItemEvent 事件。</p>
<p><strong>事件监听器</strong></p>
<p>每类事件都有对应的事件监听器，监听器是接口，根据动作来定义方法</p>
<p>使用事件监听器：实现监听器接口、使用内部类和匿名类。</p>
<p>使用事件适配器。</p>
<p><strong>多媒体处理</strong></p>
<ul>
<li>图像处理——java.awt.image</li>
<li>二维图像绘制——Java2D。</li>
<li>音频录制与播放——JavaSound。</li>
<li>视频拍照与播放——JMF。</li>
</ul>
<h3 id="正则表达式">正则表达式</h3>
<p><strong>基本语法</strong></p>
<ol>
<li>八进制表示的字符，以<code>\0</code>开头，后跟 1 ～ 3 位数字</li>
<li>十六进制表示的字符，以<code>\x</code>开头，后跟两位字符</li>
<li>Unicode 编号表示的字符，以<code>\u</code>开头，后跟 4 位字符</li>
<li>点号字符<code>.</code>是一个元字符，默认模式下，它匹配除了换行符以外的任意字符</li>
<li>以<code>(? s)</code>开头，s 表示 single line，即单行匹配模式</li>
<li>为方便表示连续的多个字符，字符组中可以使用连字符&rsquo;-&rsquo;</li>
<li>字符组支持排除的概念，在<code>[</code>后紧跟一个字符<code>^</code>,只有在字符组的开头才是元字符，如果不在开头，就是普通字符，匹配它自身</li>
<li><code>\d</code>: d 表示 digit，匹配一个数字字符</li>
<li><code>\w</code>: w 表示 word，匹配一个单词字符</li>
<li><code>\s</code>: s 表示 space，匹配一个空白字符</li>
<li><code>\D</code>：匹配一个非数字字符</li>
<li><code>\W</code>：匹配一个非单词字符</li>
<li><code>\S</code>：匹配一个非空白字符</li>
</ol>
<p><strong>量词</strong>指的是指定出现次数的元字符：</p>
<ol>
<li><code>+</code>：表示前面字符的一次或多次出现</li>
<li><code>\*</code>：表示前面字符的零次或多次出现</li>
<li><code>?</code> ：表示前面字符可能出现，也可能不出现</li>
<li>更为通用的表示出现次数的语法是<code>{m, n}</code>，出现次数从 m 到 n，包括 m 和 n，如果 n 没有限制，可以省略，如果 m 和 n 一样，可以写为<code>{m}</code></li>
<li>使用懒惰量词，在量词的后面加一个符号<code>?</code></li>
<li>表达式可以用括号<code>()</code>括起来，表示一个分组</li>
</ol>
<p><strong>特殊边界匹配</strong></p>
<ol>
<li>默认情况下，<code>^</code>匹配整个字符串的开始</li>
<li>默认情况下，<code>$</code>匹配整个字符串的结束</li>
<li><code>\A</code>与<code>^</code>类似，但不管什么模式，它匹配的总是整个字符串的开始边界。</li>
<li><code>\Z</code>和<code>\z</code>与<code>$</code>类似，但不管什么模式，它们匹配的总是整个字符串的结束边界。</li>
<li><code>\b</code>匹配的是单词边界</li>
</ol>
<p><strong>环视边界匹配</strong></p>
<p>环视的字面意思就是左右看看，需要左右符合一些条件，本质上，它也是匹配边界，对边界有一些要求，这个要求是针对左边或右边的字符串的。</p>
<ol>
<li><strong>肯定顺序环视</strong>，语法是<code>(? =...)</code>，要求右边的字符串匹配指定的表达式。</li>
<li><strong>否定顺序环视</strong>，语法是<code>(? ! ...)</code>，要求右边的字符串不能匹配指定的表达式。</li>
<li><strong>肯定逆序环视</strong>，语法是<code>(? &lt;=...)</code>，要求左边的字符串匹配指定的表达式。</li>
<li><strong>否定逆序环视</strong>，语法是<code>(? &lt;! ...)</code>，要求左边的字符串不能匹配指定的表达式。</li>
</ol>
<p>这些环视结构也被称为断言，断言的对象是边界，边界不占用字符，没有宽度，所以也被称为零宽度断言。</p>
<p><strong>Java API</strong></p>
<p>正则表达式相关的类位于包 java.util.regex 下，有两个主要的类，一个是 Pattern，另一个是 Matcher</p>
<ol>
<li>
<p>表示正则表达式</p>
<p>在 Java 中，没有什么特殊的语法能直接表示正则表达式，需要用字符串表示，而在字符串中，''也是一个元字符，为了在字符串中表示正则表达式的&rsquo;'，就需要使用两个&rsquo;'，即&rsquo;\'，而要匹配&rsquo;'本身，就需要 4 个&rsquo;'，即&rsquo;\\&rsquo;</p>
<p>三种匹配模式：单行模式（点号模式）、多行模式和大小写无关模式，它们对应的常量分别为：Pattern.DOTALL、Pattern.MULTILINE 和 Pattern.CASE_INSENSI-TIVE，多个模式可以一起使用，通过'|'连起来即可</p>
</li>
<li>
<p>切分</p>
</li>
<li>
<p>验证</p>
</li>
<li>
<p>查找</p>
</li>
<li>
<p>替换</p>
</li>
</ol>
<h3 id="list-集合">List 集合</h3>
<p>集合操作最常用的两种方法：<code>add()</code>，<code>iterator()</code></p>
<p><code>public interface List&lt;E&gt; extends Collection&lt;E&gt;</code></p>
<p>Collection 的继承关系，如图：</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/Collection.png" alt="Collection继承关系" /></p>
<p>List 的三个常用子类：</p>
<ol>
<li><code>ArrayList</code></li>
<li><code>LinkedList</code></li>
<li><code>Vector</code></li>
</ol>
<p><strong>ArrayList</strong></p>
<p>继承关系</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ArrayList</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span>
<span class="kd">extends</span> <span class="n">AbstractList</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span>
<span class="kd">implements</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;,</span> <span class="n">RandomAccess</span><span class="o">,</span> <span class="n">Cloneable</span><span class="o">,</span> <span class="n">Serializable</span>
</code></pre></td></tr></table>
</div>
</div><p><strong>LinkedList</strong></p>
<p>继承关系</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">LinkedList</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span>
<span class="kd">extends</span> <span class="n">AbstractSequentialList</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span>
<span class="kd">implements</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;,</span> <span class="n">Deque</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;,</span> <span class="n">Cloneable</span><span class="o">,</span> <span class="n">Serializable</span>
</code></pre></td></tr></table>
</div>
</div><p><strong>Vector</strong></p>
<p>Vector 是一个古老的集合（从 JDK 1.0 就有了）</p>
<p>继承关系</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Vector</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span>
<span class="kd">extends</span> <span class="n">AbstractList</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span>
<span class="kd">implements</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;,</span> <span class="n">RandomAccess</span><span class="o">,</span> <span class="n">Cloneable</span><span class="o">,</span> <span class="n">Serializable</span>
</code></pre></td></tr></table>
</div>
</div><hr />
<h3 id="set-集合">Set 集合</h3>
<p>Set 集合不允许包含相同的元素，如果试图把两个相同的元素加入同一个 Set 集合中，则添加操作失败，add 方法返回 false，且新元素不会被加入。</p>
<p>Set 判断两个对象相同不是使用==运算符，而是根据 equals 方法</p>
<p><strong>HashSet</strong></p>
<p>HashSet 按 Hash 算法来存储集合中的元素，因此具有很好的存取和查找性能。</p>
<p>HashSet 不是同步的，如果多个线程同时访问一个 HashSet，假设有两个或者两个以上线程同时修改了 HashSet 集合时，则必须通过代码来保证其同步。</p>
<p><strong>LinkedHashSet</strong></p>
<p>HashSet 还有一个子类 LinkedHashSet，LinkedHashSet 集合也是根据元素的 hashCode 值来决定元素的存储位置，但它同时使用链表维护元素的次序，这样使得元素看起来是以插入的顺序保存的。</p>
<p><strong>TreeSet</strong></p>
<p>TreeSet 是 SortedSet 接口的实现类，正如 SortedSet 名字所暗示的，TreeSet 可以确保集合元素处于排序状态。</p>
<p>TreeSet 并不是根据元素的插入顺序进行排序的，而是根据元素实际值的大小来进行排序的。</p>
<p><strong>EnumSet</strong></p>
<p>EnumSet 是一个专为枚举类设计的集合类，EnumSet 中的所有元素都必须是指定枚举类型的枚举值，该枚举类型在创建 EnumSet 时显式或隐式地指定。EnumSet 的集合元素也是有序的，EnumSet 以枚举值在 Enum 类内的定义顺序来决定集合元素的顺序。</p>
<hr />
<h3 id="map-集合">Map 集合</h3>
<p>Map 用于保存具有映射关系的数据，因此 Map 集合里保存着两组值，一组值用于保存 Map 里的 key，另外一组值用于保存 Map 里的 value，key 和 value 都可以是任何引用类型的数据。</p>
<p>Map 的继承关系，如图：</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/Map.png" alt="Map" /></p>
<p><code>HashMap</code>和<code>Hashtable</code>都是 Map 接口的典型实现类，它们之间的关系完全类似于<code>ArrayList</code>和<code>Vector</code>的关系</p>
<blockquote>
<p>Hashtable 是一个线程安全的 Map 实现，但 HashMap 是线程不安全的实现</p>
<p>Hashtable 不允许使用 null 作为 key 和 value</p>
</blockquote>
<p><code>HashMap</code>、<code>Hashtable</code>也不能保证其中 key-value 对的顺序。</p>
<p><code>Properties</code>类是<code>Hashtable</code>类的子类，正如它的名字所暗示的，该对象在处理属性文件时特别方便（Windows 操作平台上的 ini 文件就是一种属性文件）。</p>
<p><code>TreeMap</code>就是一个红黑树数据结构，每个 key-value 对即作为红黑树的一个节点。<code>TreeMap</code>存储 key-value 对（节点）时，需要根据 key 对节点进行排序。</p>
<blockquote>
<p><strong>ArrayList 和 Vector 的显著区别</strong>：ArrayList 是线程不安全的，当多个线程访问同一个 ArrayList 集合时，如果有超过一个线程修改了 ArrayList 集合，则程序必须手动保证该集合的同步性；但 Vector 集合则是线程安全的，无须程序保证该集合的同步性。</p>
</blockquote>
<h3 id="java-多线程编程">Java 多线程编程</h3>
<p>Java 是多线程的编程语言，有利于并发访问处理。</p>
<p>继承<strong>Thread 类</strong>实现多线程</p>
<p>多线程的执行的方法在<code>run()</code>中定义，</p>
<p>start()方法是并发执行</p>
<p>每一个线程类对象只允许启动一次，如果重复启动，就会抛出异常</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/JVM%E7%BA%BF%E7%A8%8B.png" alt="JVM线程" /></p>
<p><code>Runnable</code>接口的使用</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="n">Thread</span> <span class="n">th</span><span class="o">=</span><span class="k">new</span> <span class="n">Thread</span><span class="o">(</span><span class="k">new</span> <span class="n">MyThread</span><span class="o">(</span><span class="s">&#34;线程1启动&#34;</span><span class="o">));</span>
<span class="n">th</span><span class="o">.</span><span class="na">start</span><span class="o">();</span>
</code></pre></td></tr></table>
</div>
</div><h4 id="thread-与-runnable-关系">Thread 与 Runnable 关系</h4>
<p>Thread 用于实现 Runnable，如图所示：</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/Thread.png" alt="Thread与Runnable" /></p>
<p>多线程的设计之中，使用了代理设计模式的结构，用户设计的线程主体负责项目核心功能，其他辅助功能由 Thread 类实现</p>
<p>多线程开发的本质实质上是在于多个线程可以进行统一资源的抢占</p>
<p><strong>Callable 实现多线程</strong></p>
<p><code>Callable</code>的定义</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="nd">@FunctionalInterface</span>
<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Callable</span><span class="o">&lt;</span><span class="n">V</span><span class="o">&gt;</span> <span class="o">{</span>
    <span class="n">V</span> <span class="nf">call</span><span class="o">()</span> <span class="kd">throws</span> <span class="n">Exception</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>如图 Callable 的继承关系：</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/Callable.png" alt="Callable的继承关系" /></p>
<table>
<thead>
<tr>
<th align="left">Runnable</th>
<th align="left">Callable</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">JDK1.0</td>
<td align="left">JDK1.5</td>
</tr>
<tr>
<td align="left">只有 void run()，无返回值</td>
<td align="left">V call()，有返回值</td>
</tr>
</tbody>
</table>
<h4 id="线程常用操作方法">线程常用操作方法</h4>
<p>构造方法<code>public Thread(Runnable target, String name)</code></p>
<p>设置名字<code>public final synchronized void setName(String name)</code></p>
<p>取得名字<code>public final String getName()</code></p>
<p>使用 Java 命令就会启动一个 JVM 的进程，一台电脑可以同时启动若干个 JVM 进程</p>
<p>主线程可以创建若干个子线程，主线程负责处理整体流程，而子线程负责处理耗时操作</p>
<p><strong>线程休眠</strong></p>
<p>两种休眠处理方式</p>
<p>一个参数，毫秒：<code>public static native void sleep(long millis) throws InterruptedException;</code></p>
<p>两个参数，毫秒纳秒<code>public static void sleep(long millis, int nanos)throws InterruptedException</code></p>
<p>休眠的主要特点是自动实现线程的唤醒，以继续进行后续的处理，多个线程休眠是有顺序的</p>
<p><strong>线程中断</strong></p>
<p>所有的线程都能被中断，线程中断必须进行异常处理</p>
<p><strong>线程的强制执行</strong></p>
<p>正常情况下主线程和子线程交替执行</p>
<p>强制执行<code>public final void join() throws InterruptedException</code></p>
<p><strong>线程礼让</strong></p>
<p>礼让方法：<code>public static native void yield();</code></p>
<p><strong>线程优先级</strong></p>
<p>设置优先级<code>public final void setPriority(int newPriority)</code></p>
<p>获取优先级<code>public final int getPriority()</code></p>
<p>三个优先级常量</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">final</span> <span class="kd">static</span> <span class="kt">int</span> <span class="n">MIN_PRIORITY</span> <span class="o">=</span> <span class="n">1</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kd">static</span> <span class="kt">int</span> <span class="n">NORM_PRIORITY</span> <span class="o">=</span> <span class="n">5</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kd">static</span> <span class="kt">int</span> <span class="n">MAX_PRIORITY</span> <span class="o">=</span> <span class="n">10</span><span class="o">;</span>
</code></pre></td></tr></table>
</div>
</div><p>优先级高的最有可能先执行，并不是绝对先执行</p>
<h4 id="线程的同步与死锁">线程的同步与死锁</h4>
<p><strong>同步问题的引出</strong></p>
<p>系统休眠或网络延迟会产生数据不同步问题</p>
<p><strong>线程同步</strong></p>
<p>解决同步问题的关键是锁</p>
<p>关键字<code>synchronized</code></p>
<p>同步实际上会使系统的性能降低</p>
<p>解决同步问题的两种方法：同步代码块和同步方法</p>
<p><strong>线程死锁</strong></p>
<p>线程死锁就是若干个线程互相等待的状态</p>
<p>死锁是开发中不确定的状态</p>
<p>若干个线程访问同一资源时一定要进行同步处理，而过多的同步则会造成死锁</p>
<h3 id="基础类库">基础类库</h3>
<p><strong>StringBuffer 类</strong></p>
<p>构造方法：<code>public StringBuffer()</code></p>
<p>构造方法：<code>public StringBuffer(String str)</code></p>
<p>基本操作方法：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">StringBuffer</span> <span class="n">sb</span><span class="o">=</span><span class="k">new</span> <span class="n">StringBuffer</span><span class="o">(</span><span class="s">&#34;baidu&#34;</span><span class="o">);</span>
    <span class="n">sb</span><span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="s">&#34;.com&#34;</span><span class="o">).</span><span class="na">insert</span><span class="o">(</span><span class="n">0</span><span class="o">,</span><span class="s">&#34;www.&#34;</span><span class="o">);</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">sb</span><span class="o">);</span>
    <span class="n">sb</span><span class="o">.</span><span class="na">delete</span><span class="o">(</span><span class="n">0</span><span class="o">,</span><span class="n">4</span><span class="o">);</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">sb</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>字符串反转：<code>sb.reverse()</code></p>
<p><code>StringBuffer</code>属于线程安全的全部使用<code>synchronized</code>，<code>StringBuilder</code>是非线程安全的。</p>
<p><strong>CharSequence 接口</strong></p>
<p>CharSequence 是描述字符串结构的接口</p>
<table>
<thead>
<tr>
<th>String</th>
<th>StringBuffer</th>
<th>StringBuilder</th>
</tr>
</thead>
<tbody>
<tr>
<td>public final class String<br/>extends Object<br/>implements Serializable, Comparable<String>, CharSequence</td>
<td>public final class StringBuffer<br/>extends Object<br/>implements Serializable, CharSequence</td>
<td>public final class StringBuilder<br/>extends Object<br/>implements Serializable, CharSequence</td>
</tr>
</tbody>
</table>
<p><strong>Runtime 类</strong></p>
<p>在每一个 JVM 只允许提供有一个 Runtime 类的对象，所以这个类的构造方法被默认私有化了</p>
<p><strong>System 类</strong></p>
<ul>
<li>
<p>数组拷贝：<code>public static native void arraycopy(Object src,int srcPos,Object dest,int destPos,int length);</code></p>
</li>
<li>
<p>获取当前日期时间数值：<code>public static native long currentTimeMillis();</code></p>
</li>
<li>
<p>进行垃圾回收：<code>public static void gc()</code></p>
</li>
</ul>
<p><strong>Math 类</strong></p>
<p>Math 类的全部方法:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="cm">/**
</span><span class="cm">* 指定小数位数四舍五入
</span><span class="cm">* @param: [num, scale]
</span><span class="cm">* @return: double
</span><span class="cm">*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">double</span> <span class="nf">round</span><span class="o">(</span><span class="kt">double</span> <span class="n">num</span><span class="o">,</span><span class="kt">int</span> <span class="n">scale</span><span class="o">){</span>
    <span class="k">return</span> <span class="n">Math</span><span class="o">.</span><span class="na">round</span><span class="o">(</span><span class="n">num</span><span class="o">*</span><span class="n">Math</span><span class="o">.</span><span class="na">pow</span><span class="o">(</span><span class="n">10</span><span class="o">,</span><span class="n">scale</span><span class="o">))/</span><span class="n">Math</span><span class="o">.</span><span class="na">pow</span><span class="o">(</span><span class="n">10</span><span class="o">,</span><span class="n">scale</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p><strong>Random 类</strong></p>
<p>生成不包含边界的随机正整数：<code>public int nextInt(int bound)</code></p>
<p><strong>UUID 类</strong></p>
<p>UUID 是一种生成无重复字符串的一种程序类，这种程序类的主要功能是根据时间戳实现一个自动的无重复字符串定义。</p>
<p>随机获取 UUID:<code>public static UUID randomUUID()</code></p>
<p>根据字符串获取 UUID 内容:<code>public static UUID fromString(String name)</code></p>
<p><strong>Option 类</strong></p>
<p>Option 类的主要功能是进行 null 的相关处理</p>
<p>返回空数据：<code>public static&lt;T&gt; Optional&lt;T&gt; empty()</code></p>
<p>获取数据：<code>public T get()</code></p>
<p>保存数据，但是不许出现 null：<code>public static &lt;T&gt; Optional&lt;T&gt; of(T value)</code></p>
<p>保存数据，允许出现 null：<code>public static &lt;T&gt; Optional&lt;T&gt; ofNullable(T value)</code></p>
<p>空的时候返回其他数据:<code>public T orElse(T other)</code></p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/Optional.png" alt="Optional" /></p>
<p><strong>ThreadLocal 类</strong></p>
<p>构造方法：<code>public ThreadLocal()</code></p>
<p>设置数据：<code>public void set(T value)</code></p>
<p>取出数据：<code>public T get()</code></p>
<p>删除数据：<code>public void remove()</code></p>
<p><strong>Base64 类</strong></p>
<p>Base64 可以实现加密与解密的处理，包含的内部类和方法如下图：</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/Base64.png" alt="Base64" /></p>
<h3 id="比较器">比较器</h3>
<p><strong>Arrays 类</strong></p>
<p>数组的排序：<code>public static void sort(int[] a)</code></p>
<p>数组的输出：<code>public static String toString(int[] a)</code></p>
<p><strong>Comparable 比较器</strong></p>
<p>接口定义：<code>public interface Comparable&lt;T&gt;</code></p>
<p>实现比较的方法：<code>int compareTo(T o)</code></p>
<p><strong>Comparator 比较器</strong></p>
<p>Comparator 属于一种挽救的比较器支持，其主要目的是解决一些没有使用 Comparable 排序的类的对象的数组排序操作</p>
<hr />
<h3 id="红黑树原理">红黑树原理</h3>
<blockquote>
<p>红黑树（Red Black Tree） 是一种自平衡二叉查找树，是在计算机科学中用到的一种数据结构，典型的用途是实现关联数组。</p>
<p>红黑树是在 1972 年由 Rudolf Bayer 发明的，当时被称为平衡二叉 B 树（symmetric binary B-trees）。后来，在 1978 年被 Leo J. Guibas 和 Robert Sedgewick 修改为如今的“红黑树”。</p>
<p>红黑树是一种特化的 AVL 树（平衡二叉树），都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡，从而获得较高的查找性能。</p>
<p>它虽然是复杂的，但它的最坏情况运行时间也是非常良好的，并且在实践中是高效的： 它可以在 O(log n)时间内做查找，插入和删除，这里的 n 是树中元素的数目。</p>
</blockquote>
<p>红黑树的特点：</p>
<ol>
<li>每个节点不是黑色就是红色</li>
<li>根节点必须是黑色</li>
<li>叶子节点是黑色
<ul>
<li>Java 实现的红黑树使用 null 代表空节点，因此遍历红黑树时将看不到黑丝的叶子节点，反而看到每个叶子节点都是红色的</li>
</ul>
</li>
<li>红色节点的子节点必须是黑色的</li>
<li>一个节点到该节点的所有子孙节点的所有路径上包含相同数目的黑色节点</li>
</ol>
<p>利用红色节点与黑色节点实现均衡的控制</p>
<h3 id="文件操作">文件操作</h3>
<p><strong>File 类</strong></p>
<p>构造方法：<code>public File(String pathname)</code></p>
<p>构造方法：<code>public File(String parent, String child)</code></p>
<p>创建文件：<code>public boolean createNewFile() throws IOException</code></p>
<p>判断文件是否存在：<code>public boolean exists()</code></p>
<p>删除文件：<code>public boolean delete()</code></p>
<p>Windows 的路径分隔符是<code>\</code>,Linux 的路径分隔符是<code>/</code>，</p>
<p>File 类中的路径分隔符常量<code>separator</code></p>
<p>获取父路径：<code>public File getParentFile()</code></p>
<p>创建单级目录：<code>public boolean mkdir()</code></p>
<p>创建多级目录：<code>public boolean mkdirs()</code></p>
<p>是否可读：<code>public boolean canRead()</code></p>
<p>是否可写：<code>public boolean canWrite()</code></p>
<p>获取文件长度：<code>public long length()</code></p>
<p>最后得到修改时间：<code>public long lastModified()</code></p>
<p>判断是否为目录：<code>public boolean isFile()</code></p>
<p>判断是否为文件：<code>public boolean isDirectory()</code></p>
<p>列出目录：<code>public File[] listFiles()</code></p>
<hr />
<h3 id="字节流与字符流">字节流与字符流</h3>
<p>File 类只能够操作文件本身，而不能操作文件的内容</p>
<p>字节处理流：<code>OutputStream</code>（输出字节流）,<code>InputStream</code>（输入字节流）</p>
<p>字符处理流：<code>Writer</code>（输出字符流）,<code>Reader</code>（输入字符流）</p>
<p>流的操作属于资源操作，资源操作必须进行关闭处理</p>
<p><strong><code>OutputStream</code>字节输出流</strong></p>
<p>定义：<code>public abstract class OutputStream implements Closeable, Flushable</code></p>
<p><code>OutputStream</code>的继承关系如图:</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/OutputStream.png" alt="OutputStream" /></p>
<p><code>OutputStream</code>是一个公共的输出操作标准</p>
<p><code>FileOutputStream</code>是<code>OutputStream</code>的实现子类</p>
<p>【覆盖】构造方法：<code>public FileOutputStream(File file) throws FileNotFoundException</code></p>
<p>【追加】构造方法：<code>public FileOutputStream(File file, boolean append) throws FileNotFoundException</code></p>
<p><strong><code>InputStream</code>字节输入流</strong></p>
<p><code>InputStream</code>的继承关系与方法</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/InputStream.png" alt="InputStream" /></p>
<p>使用 read()方法读取的时候只能够以字节数组为主进行接收</p>
<p><strong><code>Writer</code>字符输出流</strong></p>
<p>Writer 的继承关系及方法：</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/Writer.png" alt="Writer" /></p>
<p><code>Writer</code>是字符流，字符处理的优势在于中文数据。</p>
<p><strong><code>Reader</code>字符输入流</strong></p>
<p>Reader 的构造：</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/Reader.png" alt="Reader" /></p>
<p><strong>字节流与字符流的区别</strong></p>
<p><code>OutputStream</code>不关闭可以正常保存</p>
<p><code>Writer</code>不关闭不能正常保存</p>
<p>因为<code>Writer</code>使用了缓冲区</p>
<p>涉及中文信息的都采用字符流</p>
<p><strong>转换流</strong></p>
<table>
<thead>
<tr>
<th align="left"><code>OutputStreamWriter</code></th>
<th align="left"><code>InputStreamReader</code></th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><code>public class OutputStreamWriter extends Writer</code></td>
<td align="left"><code>public class InputStreamReader extends Reader</code></td>
</tr>
<tr>
<td align="left"><code>public OutputStreamWriter(OutputStream out)</code></td>
<td align="left"><code>public InputStreamReader(InputStream in)</code></td>
</tr>
</tbody>
</table>
<p>转换流可以使字节流转换为字符流</p>
<p><code>FileWriter</code>继承结构</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/FileWriter.png" alt="FileWriter" /></p>
<p><code>FileReader</code>继承结构</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/FileReader.png" alt="FileReader" /></p>
<h3 id="io-操作深入">IO 操作深入</h3>
<p><strong>字符编码</strong></p>
<ul>
<li>GBK/GB2312：国际编码，可以描述中文信息，GB2312 只描述简体中文</li>
<li>ISO8859-1：国际通用编码，可以用于描述所有字母信息</li>
<li>UNICODE 编码：采用十六进制方式存储，可用于描述所有的文字信息</li>
<li>UTF 编码：象形文字采用十六进制编码，字母采用 ISO8859-1 编码，有利于数据传输，节省带宽</li>
<li>项目中一般都统一使用 UTF-8 编码</li>
</ul>
<p>列出系统信息<code>System.getProperties().list(System.out);</code></p>
<p><strong>内存操作流</strong></p>
<p>Java 有两类内存操作流：</p>
<ol>
<li>
<p>字节内存操作流</p>
</li>
<li>
<p>字符内存操作流</p>
</li>
</ol>
<p><strong>管道流</strong></p>
<ol>
<li>字节管道流</li>
<li>字符管道流</li>
</ol>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/%E6%B5%81%E7%BB%93%E6%9E%84.jpg" alt="流结构" /></p>
<hr />
<h3 id="输入与输出支持">输入与输出支持</h3>
<p><strong>打印流</strong></p>
<table>
<thead>
<tr>
<th align="left">PrintStream</th>
<th align="left">PrintWriter</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><code>public class PrintStream extends FilterOutputStream implements Appendable, Closeable</code></td>
<td align="left"><code>public class PrintWriter extends Writer</code></td>
</tr>
<tr>
<td align="left"><code>public PrintStream(OutputStream out)</code></td>
<td align="left"><code>public PrintWriter (Writer out)</code>,<code>public PrintWriter(OutputStream out)</code></td>
</tr>
</tbody>
</table>
<p>对文件进行操作时通常使用打印流</p>
<p><strong>System 类对 IO 的支持</strong></p>
<ul>
<li>标准输出（显示器）：<code>public final static PrintStream out = null;</code></li>
<li>错误输出：<code>public final static PrintStream err = null;</code></li>
<li>标准输入（键盘）：<code>public final static InputStream in = null;</code></li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;我是System.out&#34;</span><span class="o">);</span>
<span class="n">System</span><span class="o">.</span><span class="na">err</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;我是System.err&#34;</span><span class="o">);</span>
</code></pre></td></tr></table>
</div>
</div><p><code>System.out</code>输出黑色字体</p>
<p><code>System.err</code>输出红色字体</p>
<p><code>System.in</code>并不常用</p>
<p><strong><code>BufferedReader</code>缓冲输入流</strong></p>
<p>读取一行数据<code>public String readLine() throws IOException</code></p>
<p><strong>Scanner 扫描流</strong></p>
<p>构造：<code>public Scanner(InputStream source)</code></p>
<p>判断是否有数据：<code>public boolean hasNext()</code></p>
<p>取出数据：<code>public String next()</code></p>
<p>设置分隔符：<code>public Scanner useDelimiter(Pattern pattern)</code></p>
<h3 id="对象序列化">对象序列化</h3>
<blockquote>
<p>序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间，对象将其当前状态写入到临时或持久性存储区。以后，可以通过从存储区中读取或反序列化对象的状态，重新创建该对象。</p>
</blockquote>
<p>Person 类产生的每一个对象都可以实现二进制的数据传输，属于可以被序列化的程序类</p>
<p><strong>序列化与反序列化</strong></p>
<table>
<thead>
<tr>
<th align="left">序列化</th>
<th align="left">反序列化</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><code>ObjectOutputStream</code></td>
<td align="left"><code>ObjectInputStream</code></td>
</tr>
<tr>
<td align="left"><code>public class ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants</code></td>
<td align="left"><code>public class ObjectInputStream extends InputStream implements ObjectInput, ObjectStreamConstants</code></td>
</tr>
<tr>
<td align="left"><code>public ObjectOutputStream(OutputStream out) throws IOException</code></td>
<td align="left"><code>public ObjectInputStream(InputStream in) throws IOException</code></td>
</tr>
<tr>
<td align="left"><code>public final void writeObject(Object obj) throws IOException</code></td>
<td align="left"><code>public final Object readObject() throws IOException, ClassNotFoundException</code></td>
</tr>
</tbody>
</table>
<p>在 Java 中的序列化与反序列化必须使用内部提供的对象操作流，如果要实现一组对象的序列化，则可以使用对象数组完成</p>
<p><strong>transient 关键字</strong></p>
<p>默认情况下当执行了对象序列化的时候会将类中的全部属性的内容进行全部的序列化操作，但是很多情况下有一些属性可能并不需要进行序列化的处理。</p>
<p><code>private transient String name;</code></p>
<p>进行序列化处理的时候，<code>name</code>属性的内容是不会被保存下来的，换言之，读取的数据<code>name</code>将是其对应数据类型的默认值<code>null</code></p>
<hr />
<h3 id="反射机制">反射机制</h3>
<blockquote>
<p>所有的技术实现的目标只有一点：重用性</p>
</blockquote>
<p>根据实例化对象反推出其类型</p>
<ol>
<li>获取 Class 对象信息：<code>public final Class&lt;?&gt; getClass()</code>
<ul>
<li>class 类定义：<code>public final class Class&lt;T&gt; implements java.io.Serializable,GenericDeclaration,Type,AnnotatedElement</code></li>
</ul>
</li>
<li>JVM 直接支持采用“类.class”的形式实例化</li>
<li>Class.forName().<code>public static Class&lt;?&gt; forName(String className) throws ClassNotFoundException</code></li>
</ol>
<p><strong>反射实例化对象</strong></p>
<p>通过<code>public T newInstance()</code>实例化对象</p>
<p>相当于“<code>类名 对象名 = new 类()</code>”，但是该方法只能调用无参构造，JDK9 之后被废弃</p>
<hr />
<h3 id="集合工具类">集合工具类</h3>
<p><strong>Stack 类</strong></p>
<p>入栈<code>public E push(E item)</code></p>
<p>出栈<code>public synchronized E pop()</code></p>
<p>Stack 的继承结构如下：</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/Stack.png" alt="stack" /></p>
<p>空栈时出栈会出现<code>Exception in thread &quot;main&quot; java.util.EmptyStackException</code></p>
<p><strong>Queue 接口</strong></p>
<p>追加数据：<code>boolean add(E e);</code>或<code>boolean offer(E e);</code></p>
<p>通过队列获取数据：<code>E poll();</code>弹出后删除数据</p>
<p>优先级队列<code>PriorityQueue</code></p>
<p><strong>Properties 属性操作</strong></p>
<p>Properties 类只能操作 String</p>
<p>使用 Properties 类型的最大特点是可以进行资源内容的输入与输出的处理操作</p>
<p><strong>Collections 类</strong></p>
<p>解释 Collection 与 Collections 的区别</p>
<ul>
<li>Collection 是集合接口，允许保存单值对象</li>
<li>Collections 是集合操作的工具类。</li>
</ul>
<h3 id="stream-数据流">Stream 数据流</h3>
<p><strong>Stream 基础操作</strong></p>
<p>Stream 主要功能是进行数据的分析处理，主要是针对于集合中的数据进行分析操作</p>
<p>可以通过函数式编程进行数据的流式处理</p>
<p><strong>数据采集</strong></p>
<p><code>&lt;R, A&gt; R collect(Collector&lt;? super T, A, R&gt; collector);</code></p>
<p><strong>分页处理方法</strong></p>
<ul>
<li>
<p>设置取出的最大数据量：<code>Stream&lt;T&gt; limit(long maxSize);</code></p>
</li>
<li>
<p>跳过指定数据量：<code>Stream&lt;T&gt; skip(long n);</code></p>
</li>
</ul>
<p><strong>MapReduce 基础模型</strong></p>
<p><code>all.stream()</code>用于初始化 Stream 对象</p>
<p><code>.filter((ele)-&gt;ele.getName().contains(&quot;小米&quot;))</code>过滤出商品名称中含有小米的数据。</p>
<p><code>.mapToDouble((olderObject)-&gt;olderObject.getPrice()*olderObject.getCount()).summaryStatistics();</code>计算出单种商品的总价，然后返回<code>DoubleSummaryStatistics</code>类型的对象。</p>
<p><code>DoubleSummaryStatistics</code>一些常用的方法</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/DoubleSummaryStatistics.png" alt="DoubleSummaryStatistics" /></p>
<hr />
<h3 id="网络编程">网络编程</h3>
<p>针对网络程序的开发有两种模型：</p>
<ol>
<li>C/S（Client/Server，客户端与服务器端）</li>
<li>B/S（Browser/Server，浏览器与服务器端）</li>
</ol>
<p>TCP（可靠的数据连接）</p>
<p>UDP（不可靠的数据连接）</p>
<p><strong>TCP</strong></p>
<p>TCP 的程序开发是网络程序最基本的开发模型，其核心的特点是使用两个类实现数据的交互处理：ServerSocket（服务器端），Socket（客户端）</p>
<p>简要工作流程如图：</p>
<p><img src="https://cdn.jsdelivr.net/gh/eternidad33/picbed@master/img/Socket.png" alt="Scoket" /></p>
<p>ServerSocket 的主要目的是设置服务器监听的端口，Socket 要指明要连接的服务器地址与端口</p>
<p><strong>UDP</strong></p>
<p>UDP 程序是基于数据报的网络编程实现，如果想实现 UDP 程序需要两个类：<code>DatagramSocket</code>和<code>DatagramPacket</code></p>
<h3 id="jdbc">JDBC</h3>
<p>对于 JDBC 的程序数据库的访问分为如下四种形式：</p>
<ol>
<li>
<p>JDBC-ODBC 桥连接</p>
<p>处理流程：程序 →JDBC→ODBC→ 数据库</p>
</li>
<li>
<p>JDBC 连接：直接通过 JDBC 进行数据库的连接</p>
<p>处理流程：程序 →JDBC→ 数据库</p>
</li>
<li>
<p>JDBC 网络连接：通过特定的网络协议连接指定的数据库服务</p>
<p>处理流程：程序 →JDBC→ 网络数据库(IP 地址，端口号)</p>
</li>
<li>
<p>JDBC 协议连接</p>
</li>
</ol>
<p>Java 访问 MySQL 过程；</p>
<ol>
<li>
<p>设置驱动</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="err">`</span><span class="kd">static</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">JDBC_DRIVER</span> <span class="o">=</span> <span class="s">&#34;com.mysql.jdbc.Driver&#34;</span><span class="o">;</span>
</code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>设置数据库地址</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="kd">static</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">DB_URL</span> <span class="o">=</span> <span class="s">&#34;jdbc:mysql://localhost:3308/test&#34;</span><span class="o">;</span>
</code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>设置用户名和密码</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="kd">static</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">USER</span> <span class="o">=</span> <span class="s">&#34;root&#34;</span><span class="o">;</span>
<span class="kd">static</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">PASS</span> <span class="o">=</span> <span class="s">&#34;123456&#34;</span><span class="o">;</span>
</code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>初始化连接对象和游标对象</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="n">Connection</span> <span class="n">conn</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
<span class="n">Statement</span> <span class="n">stmt</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
</code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>注册 JDBC 驱动</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="n">Class</span><span class="o">.</span><span class="na">forName</span><span class="o">(</span><span class="n">JDBC_DRIVER</span><span class="o">);</span>
</code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>打开连接</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="n">conn</span> <span class="o">=</span> <span class="n">DriverManager</span><span class="o">.</span><span class="na">getConnection</span><span class="o">(</span><span class="n">DB_URL</span><span class="o">,</span> <span class="n">USER</span><span class="o">,</span> <span class="n">PASS</span><span class="o">);</span>
</code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>执行查询语句</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34; 实例化Statement对象...&#34;</span><span class="o">);</span>
<span class="n">stmt</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="na">createStatement</span><span class="o">();</span>
<span class="n">String</span> <span class="n">sql</span><span class="o">;</span>
<span class="n">sql</span> <span class="o">=</span> <span class="s">&#34;SELECT id, name, url FROM websites&#34;</span><span class="o">;</span>
<span class="n">ResultSet</span> <span class="n">rs</span> <span class="o">=</span> <span class="n">stmt</span><span class="o">.</span><span class="na">executeQuery</span><span class="o">(</span><span class="n">sql</span><span class="o">);</span>
</code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>用<code>ResultSet</code>对象接收返回结果</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="n">ResultSet</span> <span class="n">rs</span> <span class="o">=</span> <span class="n">stmt</span><span class="o">.</span><span class="na">executeQuery</span><span class="o">(</span><span class="n">sql</span><span class="o">);</span>
</code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>遍历<code>ResultSet</code>对象</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="k">while</span> <span class="o">(</span><span class="n">rs</span><span class="o">.</span><span class="na">next</span><span class="o">())</span> <span class="o">{</span>
    <span class="c1">// 通过字段检索
</span><span class="c1"></span>    <span class="kt">int</span> <span class="n">id</span> <span class="o">=</span> <span class="n">rs</span><span class="o">.</span><span class="na">getInt</span><span class="o">(</span><span class="s">&#34;id&#34;</span><span class="o">);</span>
    <span class="n">String</span> <span class="n">name</span> <span class="o">=</span> <span class="n">rs</span><span class="o">.</span><span class="na">getString</span><span class="o">(</span><span class="s">&#34;name&#34;</span><span class="o">);</span>
    <span class="n">String</span> <span class="n">url</span> <span class="o">=</span> <span class="n">rs</span><span class="o">.</span><span class="na">getString</span><span class="o">(</span><span class="s">&#34;url&#34;</span><span class="o">);</span>
    <span class="c1">// 输出数据
</span><span class="c1"></span>    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">print</span><span class="o">(</span><span class="s">&#34;ID: &#34;</span> <span class="o">+</span> <span class="n">id</span><span class="o">);</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">print</span><span class="o">(</span><span class="s">&#34;, 站点名称: &#34;</span> <span class="o">+</span> <span class="n">name</span><span class="o">);</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">print</span><span class="o">(</span><span class="s">&#34;, 站点 URL: &#34;</span> <span class="o">+</span> <span class="n">url</span><span class="o">);</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">print</span><span class="o">(</span><span class="s">&#34;\n&#34;</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>关闭资源</p>
</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-java" data-lang="java"><span class="n">rs</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
<span class="n">stmt</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
<span class="n">conn</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
</code></pre></td></tr></table>
</div>
</div><p>运行结果：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-shell" data-lang="shell">Thu Apr <span class="m">09</span> 18:03:44 CST <span class="m">2020</span> WARN: Establishing SSL connection without server<span class="s1">&#39;s identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn&#39;</span>t set. For compliance with existing applications not using SSL the verifyServerCertificate property is <span class="nb">set</span> to <span class="s1">&#39;false&#39;</span>. You need either to explicitly disable SSL by setting <span class="nv">useSSL</span><span class="o">=</span>false, or <span class="nb">set</span> <span class="nv">useSSL</span><span class="o">=</span><span class="nb">true</span> and provide truststore <span class="k">for</span> server certificate verification.
 实例化Statement对象...
ID: 1, 站点名称: Google, 站点 URL: https://www.google.cm/
ID: 2, 站点名称: 淘宝, 站点 URL: https://www.taobao.com/
ID: 3, 站点名称: 菜鸟教程, 站点 URL: http://www.runoob.com
ID: 4, 站点名称: 微博, 站点 URL: http://weibo.com/
ID: 5, 站点名称: Facebook, 站点 URL: https://www.facebook.com/
Goodbye!
</code></pre></td></tr></table>
</div>
</div><blockquote>
<p>MySQL 8.0 以上版本需设置 JDBC 为<code>static final String JDBC_DRIVER = &quot;com.mysql.cj.jdbc.Driver&quot;;</code></p>
</blockquote>

    </article>
    
    <script>
  'use strict';
  
  function wrap(el, wrapper) {
    el.parentNode.insertBefore(wrapper, el);
    wrapper.appendChild(el);
  }

  (function () {
    var singleContentsElem = document.querySelector('.single__contents');
    singleContentsElem ? 
    singleContentsElem.querySelectorAll('pre > code').forEach(function(elem) {
      var dataLang = elem.getAttribute('data-lang');
      var dataLangWrapper = document.createElement('div');
      var code = null;
      var codeTitle = null;

      if (dataLang && dataLang.includes(':')) {
        code = dataLang.split(':')[0];
        codeTitle = dataLang.split(':')[1];

        dataLangWrapper.className = 'language-' + code;
        dataLangWrapper.setAttribute('data-lang', codeTitle);

        elem.className = 'language-' + code;
        elem.setAttribute('data-lang', codeTitle);
        elem.setAttribute('id', codeTitle);
      } else if (!dataLang) {
        dataLangWrapper.setAttribute('data-lang', 'Code');
        dataLangWrapper.className = 'language-code';
      }

      if (!dataLang || codeTitle) {
        wrap(elem.parentNode, dataLangWrapper);
      }

    }) : null;
  })();

  var langCodeElem = document.querySelectorAll('.language-code');
  langCodeElem ? langCodeElem.forEach(function (elem) {
    var newElem = document.createElement('span');
    newElem.className = 'copy-to-clipboard';
    newElem.setAttribute('title', 'Copy to clipboard');
    elem.append(newElem);
  }) : null;
  
</script>
    
<div class="donation">
  <div class="donation__message">
    分享
  </div>
  <div class="donation__icons">
    
    
    
      
        <a href="javascript:void(function(){var d=document,e=encodeURIComponent,s1=window.getSelection,s2=d.getSelection,s3=d.selection,s=s1?s1():s2?s2():s3?s3.createRange().text:'',r='http://service.weibo.com/share/share.php?url='+e(d.location.href)+'&title='+e(d.title),x=function(){if(!window.open(r,'weibo','toolbar=0,resizable=1,scrollbars=yes,status=1,width=450,height=330'))location.href=r+'&r=1'};if(/Firefox/.test(navigator.userAgent)){setTimeout(x,0)}else{x()}})()" class="donation__item" target="_blank" rel="noreferer" title="Weibo" aria-label="Weibo Share Button" data-type="share">
          <svg data-name="weibo" enable-background="new 0 0 24 24" viewBox="0 0 24 24" width="35" height="35" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path d="m23.977 8.171c.103 1.315-.123 2.891-1.006 2.969-1.442.127-.69-1.435-.671-2.375.053-2.725-2.312-4.618-4.629-4.618-.656 0-2.181.438-1.946-.924.106-.6.623-.592 1.14-.66 3.897-.51 6.838 2.125 7.112 5.608z"/><path d="m17.604 11.337c1.675.901 3.687 1.35 3.354 4.024-.614 4.929-11.054 8.24-17.575 4.618-1.788-.994-3.639-2.448-3.354-5.344.246-2.493 1.95-4.424 3.623-6.069 1.596-1.57 3.278-2.798 5.567-3.364 2.484-.614 3.218 1.422 2.549 3.43 1.439-.095 4.488-1.674 5.836-.132.594.68.367 1.897 0 2.837zm-1.811 6.333c.537-.598 1.076-1.51 1.073-2.572-.01-4.395-7.635-5.376-11.806-2.969-4.747 2.74-2.743 7.664 3.086 8.048 3.088.204 6.179-.868 7.647-2.507z"/><path d="m19.952 10.084c-.977.064-.612-.658-.671-1.517-.037-.529-.483-1.14-.872-1.32-.763-.352-1.945.256-1.945-.791 0-.778.686-.697 1.074-.726 3.555-.266 3.775 4.265 2.414 4.354z"/><path d="m12.842 14.768c1.429 4.248-6.017 6.223-7.379 2.573-.911-2.441 1.277-4.383 3.555-4.618 1.945-.201 3.395.775 3.824 2.045zm-3.422.726c.303.516 1 .145.939-.264-.073-.473-.945-.403-.939.264zm-1.207 2.243c1.252-.293 1.42-2.612-.47-2.177-1.587.364-1.28 2.586.47 2.177z"/></svg>
        </a>
      
    
      
        <a href="javascript:void(function(){var d=document,e=encodeURIComponent,s1=window.getSelection,s2=d.getSelection,s3=d.selection,s=s1?s1():s2?s2():s3?s3.createRange().text:'',r='https://www.douban.com/recommend/?url='+e(d.location.href)+'&title='+e(d.title)+'&sel='+e(s)+'&v=1',w=450,h=330,x=function(){if(!window.open(r,'douban','toolbar=0,resizable=1,scrollbars=yes,status=1,width='+w+',height='+h+',left='+(screen.width-w)/2+',top='+(screen.height-h)/2))location.href=r+'&r=1'};if(/Firefox/.test(navigator.userAgent)){setTimeout(x,0)}else{x()}})()" class="donation__item" target="_blank" rel="noreferer" title="Douban" aria-label="Douban Share Button" data-type="share">
          <svg data-name="douban" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="35" height="35"><path fill="currentColor" d="M 4 4 A 1.0001 1.0001 0 1 0 4 6 L 20 6 A 1.0001 1.0001 0 1 0 20 4 L 4 4 z M 7 8 C 5.9069372 8 5 8.9069372 5 10 L 5 13 C 5 14.093063 5.9069372 15 7 15 L 7.2792969 15 L 8.6113281 19 L 4 19 A 1.0001 1.0001 0 1 0 4 21 L 20 21 A 1.0001 1.0001 0 1 0 20 19 L 15.388672 19 L 16.720703 15 L 17 15 C 18.093063 15 19 14.093063 19 13 L 19 10 C 19 8.9069372 18.093063 8 17 8 L 7 8 z M 7 10 L 17 10 L 17 13 L 7 13 L 7 10 z M 9.3886719 15 L 14.611328 15 L 13.279297 19 L 10.720703 19 L 9.3886719 15 z"/></svg>
        </a>
      
    
  </div>
</div>

    
<div class="donation">
  <div class="donation__message">
    您的鼓励是我最大的动力
  </div>
  <div class="donation__icons">
    
      
        
          <div class="donation__item donation__dropup" title="alipay" aria-label="alipay" data-type="donation">
            <svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="35" height="35"><path fill="#00A1E9" d="M 5 5 L 5 27 L 27 27 L 27 5 L 5 5 z M 7 7 L 25 7 L 25 18.931641 L 18.929688 16.775391 C 19.528069 15.604874 19.872428 14.319295 20 13 L 17 13 L 17 12 L 21 12 L 21 11 L 17 11 L 17 9 L 15 9 L 15 11 L 10 11 L 10 12 L 15 12 L 15 13 L 11 13 L 11 14 L 18.042969 14 C 17.874523 14.798238 17.595556 15.553113 17.226562 16.220703 C 17.067744 16.141588 16.909631 16.060926 16.748047 15.988281 C 16.275047 15.769281 15.785203 15.594937 15.283203 15.460938 C 14.281203 15.185937 13.248844 15.029953 12.214844 15.001953 C 11.955844 14.994953 11.6955 15.005813 11.4375 15.007812 C 11.1535 15.021812 10.861031 15.045953 10.582031 15.126953 C 10.020031 15.271953 9.5026563 15.571516 9.0976562 15.978516 C 8.2506563 16.776516 7.9028281 17.969375 8.0488281 19.109375 C 8.1738281 20.285375 9.0837031 21.364953 10.220703 21.751953 C 10.770703 21.960953 11.416641 22.039422 11.931641 21.982422 C 12.202641 21.976422 12.472188 21.956297 12.742188 21.904297 C 13.013188 21.866297 13.281922 21.822234 13.544922 21.740234 C 14.607922 21.469234 15.606062 20.931031 16.414062 20.207031 C 16.818062 19.845031 17.187578 19.452297 17.517578 19.029297 C 17.673578 18.811297 17.84375 18.601328 17.96875 18.361328 C 17.986598 18.324421 17.999073 18.284503 18.017578 18.248047 L 25 22.044922 L 25 25 L 7 25 L 7 7 z M 11.427734 16.341797 L 12.109375 16.388672 C 13.020375 16.473672 13.909156 16.711516 14.785156 16.978516 C 15.220156 17.122516 15.651125 17.283172 16.078125 17.451172 C 16.169125 17.488172 16.257656 17.530313 16.347656 17.570312 C 16.265656 17.685312 16.183703 17.800109 16.095703 17.912109 C 15.835703 18.249109 15.532328 18.544703 15.236328 18.845703 C 14.636328 19.436703 13.928094 19.918141 13.121094 20.244141 C 12.921094 20.332141 12.710094 20.385547 12.496094 20.435547 C 12.284094 20.499547 12.06575 20.534594 11.84375 20.558594 C 11.37975 20.644594 11.008375 20.634062 10.609375 20.539062 C 9.834375 20.367062 9.1521562 19.755547 9.0351562 18.935547 C 8.8801563 18.121547 9.246 17.233016 9.875 16.791016 C 10.182 16.559016 10.534719 16.428234 10.886719 16.365234 C 11.064719 16.330234 11.241734 16.336797 11.427734 16.341797 z"/></svg>
            <div class="donation__dropup--content">
              <img data-src="/images/pay/alipay.jpg" alt="alipay QR Code" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload"/>
            </div>
          </div>        
        
      
    
      
    
      
        
          <div class="donation__item donation__dropup" title="wechat" aria-label="wechat" data-type="donation">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="35" height="35"><path fill="#8BC34A" d="M18,6C9.2,6,2,12,2,19.5c0,4.3,2.3,8,6,10.5l-2,6l6.3-3.9C14,32.7,16,33,18,33c8.8,0,16-6,16-13.5C34,12,26.8,6,18,6z"/><path fill="#7CB342" d="M20,29c0-6.1,5.8-11,13-11c0.3,0,0.6,0,0.9,0c-0.1-0.7-0.3-1.4-0.5-2c-0.1,0-0.3,0-0.4,0c-8.3,0-15,5.8-15,13c0,1.4,0.3,2.7,0.7,4c0.7,0,1.4-0.1,2.1-0.2C20.3,31.6,20,30.3,20,29z"/><path fill="#CFD8DC" d="M46,29c0-6.1-5.8-11-13-11c-7.2,0-13,4.9-13,11s5.8,11,13,11c1.8,0,3.5-0.3,5-0.8l5,2.8l-1.4-4.8C44.3,35.2,46,32.3,46,29z"/><path fill="#33691E" d="M14,15c0,1.1-0.9,2-2,2s-2-0.9-2-2s0.9-2,2-2S14,13.9,14,15z M24,13c-1.1,0-2,0.9-2,2s0.9,2,2,2s2-0.9,2-2S25.1,13,24,13z"/><path fill="#546E7A" d="M30,26.5c0,0.8-0.7,1.5-1.5,1.5S27,27.3,27,26.5s0.7-1.5,1.5-1.5S30,25.7,30,26.5z M37.5,25c-0.8,0-1.5,0.7-1.5,1.5s0.7,1.5,1.5,1.5s1.5-0.7,1.5-1.5S38.3,25,37.5,25z"/></svg>
            <div class="donation__dropup--content">
              <img data-src="/images/pay/wechat.png" alt="wechat QR Code" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload"/>
            </div>
          </div>        
        
      
    
  </div>
</div>

    
<div class="whoami__gutter"></div>
<hr class="hr-slash whoami-hr"/>
<section class="whoami">
  <div class="whoami__image-wrapper">
    
    
      
        <img data-src="/images/whoami/avatar.jpg" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" alt="Vigilr" class="lazyload whoami__image"/>
      
    
  </div>
  <div class="whoami__contents">
    <div class="whoami__written-by">
      作者
    </div>
    <div class="whoami__title">
      
        Vigilr
      
    </div>
    <div class="whoami__desc">
      
        大四学生
      
    </div>
    <div class="whoami__social">
      
      
      <a href="https://blog.csdn.net/qq_42907802" title="csdn" aria-label="csdn">
        <svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="25" height="25"><path fill="currentColor" d="M11.705 9.681l-.03.247c-.035.288-.3.484-.585.439-.47-.081-1.135-.151-1.64-.151-.765 0-1.16.267-1.19.56-.035.368.365.389 1.355.681 1.345.378 1.935.913 1.855 1.741C11.38 14.172 10.31 15 8.165 15c-.655 0-1.24-.096-1.675-.222-.24-.066-.395-.293-.37-.545l.035-.288c.045-.232.25-.404.49-.404.035 0 .065.005.095.01.01 0 1.057.237 1.61.202.808-.051 1.26-.247 1.3-.636.03-.353-.3-.404-1.22-.646-1.265-.343-2.075-.878-1.995-1.731C6.53 9.752 7.72 9 9.555 9 10.2 9 10.83 9.035 11.3 9.121 11.56 9.167 11.74 9.414 11.705 9.681zM18.79 9.814c.019-.223.184-.409.404-.45 4.533-.849 4.929.926 4.782 2.502l-.241 2.54c-.024.257-.24.453-.498.453h-.546c-.295 0-.526-.254-.498-.547l.207-2.182c.056-.601.405-1.776-1.281-1.732-.186.005-.343.017-.469.032-.235.027-.414.218-.433.455-.021.255-.05.595-.083.88l-.251 2.642c-.024.257-.24.453-.498.453h-.514c-.296 0-.527-.255-.498-.549l.247-2.501L18.79 9.814zM17.115 9.846c-.615-.5-1.611-.696-2.84-.735-.531-.017-1.087.024-1.265.05-.192.029-.345.19-.385.38-.01.035-.015.07-.015.11l-.43 4.635c-.03.275.17.52.44.545.425.045.91.065 1.41.065 1.205 0 2.005-.18 2.64-.59.695-.44 1.17-1.15 1.265-2.16C18.035 11.056 17.665 10.306 17.115 9.846zM16.435 12.106c-.085.935-.955 1.605-2.185 1.605-.305 0-.46-.025-.58-.05l.3-3.355c.125-.025.36-.025.525-.025C15.795 10.271 16.565 10.746 16.435 12.106zM5.367 14.461c-.021.227-.19.41-.415.448C4.623 14.966 4.163 15 3.595 15c-2.427 0-3.737-1.254-3.583-2.913C.198 10.112 2.139 9 4.264 9c.559 0 .961.034 1.304.093.259.045.437.286.408.547L5.941 9.965c-.031.283-.292.487-.573.439-.326-.055-.724-.093-1.071-.093-1.25 0-2.312.41-2.434 1.707-.109 1.16.637 1.714 2.044 1.714.271 0 .614-.024.922-.064.318-.041.592.222.562.541L5.367 14.461z"/></svg>
      </a>
      
      
      
      
      
      <a href="mailto:tfl2020@foxmail.com" title="email" aria-label="email">
        <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path fill="currentColor" d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-.4 4.25l-7.07 4.42c-.32.2-.74.2-1.06 0L4.4 8.25c-.25-.16-.4-.43-.4-.72 0-.67.73-1.07 1.3-.72L12 11l6.7-4.19c.57-.35 1.3.05 1.3.72 0 .29-.15.56-.4.72z"/></svg>
      </a>
      
      
      
      <a href="https://github.com/eternidad33/" title="github" aria-label="github">
        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="25" height="25" viewBox="0 0 24 24" version="1.1">
<g id="surface3680">
<path fill="currentColor" d="M 10.898438 2.101562 C 6.300781 2.601562 2.601562 6.300781 2.101562 10.800781 C 1.601562 15.5 4.300781 19.699219 8.398438 21.300781 C 8.699219 21.398438 9 21.199219 9 20.800781 L 9 19.199219 C 9 19.199219 8.601562 19.300781 8.101562 19.300781 C 6.699219 19.300781 6.101562 18.101562 6 17.398438 C 5.898438 17 5.699219 16.699219 5.398438 16.398438 C 5.101562 16.300781 5 16.300781 5 16.199219 C 5 16 5.300781 16 5.398438 16 C 6 16 6.5 16.699219 6.699219 17 C 7.199219 17.800781 7.800781 18 8.101562 18 C 8.5 18 8.800781 17.898438 9 17.800781 C 9.101562 17.101562 9.398438 16.398438 10 16 C 7.699219 15.5 6 14.199219 6 12 C 6 10.898438 6.5 9.800781 7.199219 9 C 7.101562 8.800781 7 8.300781 7 7.601562 C 7 7.199219 7 6.601562 7.300781 6 C 7.300781 6 8.699219 6 10.101562 7.300781 C 10.601562 7.101562 11.300781 7 12 7 C 12.699219 7 13.398438 7.101562 14 7.300781 C 15.300781 6 16.800781 6 16.800781 6 C 17 6.601562 17 7.199219 17 7.601562 C 17 8.398438 16.898438 8.800781 16.800781 9 C 17.5 9.800781 18 10.800781 18 12 C 18 14.199219 16.300781 15.5 14 16 C 14.601562 16.5 15 17.398438 15 18.300781 L 15 20.898438 C 15 21.199219 15.300781 21.5 15.699219 21.398438 C 19.398438 19.898438 22 16.300781 22 12.101562 C 22 6.101562 16.898438 1.398438 10.898438 2.101562 Z M 10.898438 2.101562 "/>
</g>
</svg>

      </a>
      
      
      
      <a href="https://www.jianshu.com/u/651a6ee53f49" title="jianshu" aria-label="jianshu">
        <svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="25" height="25"><path fill="currentColor" d="M 6.8886719 1 C 6.4046719 1 6.0053906 1.3483125 5.9003906 1.8203125 C 5.6373906 2.9983125 4.7908438 5.0488437 2.5898438 6.0898438 C 2.2388438 6.2558437 2 6.5914688 2 6.9804688 L 2 7.0253906 C 2 7.6933906 2.6699687 8.1785 3.2929688 7.9375 C 3.7418759 7.7640455 4.1405134 7.5528964 4.5117188 7.3242188 A 1.0001 1.0001 0 0 0 4.7910156 8.2363281 C 4.7910156 8.2363281 5 8.3770193 5 9 A 1.0001 1.0001 0 1 0 7 9 C 7 7.6889807 6.2109375 6.8261719 6.2109375 6.8261719 A 1.0001 1.0001 0 0 0 5.5605469 6.5253906 C 6.0753568 6.0530628 6.4913817 5.5365138 6.8203125 5 L 7.3105469 5 C 7.623843 5.4287314 7.8943972 5.9150433 8.0332031 6.3222656 C 8.1712031 6.7272656 8.5554219 6.9921875 8.9824219 6.9921875 C 9.6734219 6.9921875 10.152453 6.3171562 9.9394531 5.6601562 C 9.869187 5.442609 9.7517566 5.2213533 9.6210938 5 L 11 5 C 11.552 5 12 4.552 12 4 C 12 3.448 11.552 3 11 3 L 7.703125 3 C 7.7849123 2.711735 7.8509558 2.4314303 7.8964844 2.1699219 C 8.0024844 1.5569219 7.5223906 1 6.9003906 1 L 6.8886719 1 z M 16.888672 1 C 16.404672 1 16.005391 1.3483125 15.900391 1.8203125 C 15.638391 2.9983125 14.790844 5.0488437 12.589844 6.0898438 C 12.238844 6.2558437 12 6.5914688 12 6.9804688 L 12 7.0253906 C 12 7.6933906 12.669969 8.1785 13.292969 7.9375 C 14.996474 7.2792779 16.101927 6.1717473 16.820312 5 L 17.310547 5 C 17.623843 5.4287314 17.894397 5.9150433 18.033203 6.3222656 C 18.171203 6.7272656 18.555422 6.9921875 18.982422 6.9921875 C 19.673422 6.9921875 20.152453 6.3171562 19.939453 5.6601562 C 19.869187 5.442609 19.751757 5.2213533 19.621094 5 L 21 5 C 21.552 5 22 4.552 22 4 C 22 3.448 21.552 3 21 3 L 17.703125 3 C 17.784912 2.711735 17.850956 2.4314303 17.896484 2.1699219 C 18.002484 1.5569219 17.522391 1 16.900391 1 L 16.888672 1 z M 9 8 A 1.0001 1.0001 0 1 0 9 10 L 18 10 L 18 19 C 18 19.56503 17.56503 20 17 20 L 16 20 A 1.0001 1.0001 0 1 0 16 22 L 17 22 C 18.64497 22 20 20.64497 20 19 L 20 9 A 1.0001 1.0001 0 0 0 19 8 L 9 8 z M 4.984375 10.986328 A 1.0001 1.0001 0 0 0 4 12 L 4 21 A 1.0001 1.0001 0 1 0 6 21 L 6 12 A 1.0001 1.0001 0 0 0 4.984375 10.986328 z M 9 12 A 1.0001 1.0001 0 0 0 8 13 L 8 19 A 1.0001 1.0001 0 0 0 9 20 L 13 20 C 14.64497 20 16 18.64497 16 17 L 16 16.167969 A 1.0001 1.0001 0 0 0 16 15.841797 L 16 13 A 1.0001 1.0001 0 0 0 15 12 L 9 12 z M 10 14 L 14 14 L 14 15 L 10 15 L 10 14 z M 10 17 L 14 17 C 14 17.56503 13.56503 18 13 18 L 10 18 L 10 17 z"/></svg>
      </a>
      
      
      
      <a href="tel:12345678900" title="phone" aria-label="phone">
        <svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="25" height="25"><path fill="currentColor" d="M 8.65625 3 C 8.132813 3 7.617188 3.1875 7.1875 3.53125 L 7.125 3.5625 L 7.09375 3.59375 L 3.96875 6.8125 L 4 6.84375 C 3.035156 7.734375 2.738281 9.066406 3.15625 10.21875 C 3.160156 10.226563 3.152344 10.242188 3.15625 10.25 C 4.003906 12.675781 6.171875 17.359375 10.40625 21.59375 C 14.65625 25.84375 19.402344 27.925781 21.75 28.84375 L 21.78125 28.84375 C 22.996094 29.25 24.3125 28.960938 25.25 28.15625 L 28.40625 25 C 29.234375 24.171875 29.234375 22.734375 28.40625 21.90625 L 24.34375 17.84375 L 24.3125 17.78125 C 23.484375 16.953125 22.015625 16.953125 21.1875 17.78125 L 19.1875 19.78125 C 18.464844 19.433594 16.742188 18.542969 15.09375 16.96875 C 13.457031 15.40625 12.621094 13.609375 12.3125 12.90625 L 14.3125 10.90625 C 15.152344 10.066406 15.167969 8.667969 14.28125 7.84375 L 14.3125 7.8125 L 14.21875 7.71875 L 10.21875 3.59375 L 10.1875 3.5625 L 10.125 3.53125 C 9.695313 3.1875 9.179688 3 8.65625 3 Z M 8.65625 5 C 8.730469 5 8.804688 5.035156 8.875 5.09375 L 12.875 9.1875 L 12.96875 9.28125 C 12.960938 9.273438 13.027344 9.378906 12.90625 9.5 L 10.40625 12 L 9.9375 12.4375 L 10.15625 13.0625 C 10.15625 13.0625 11.304688 16.136719 13.71875 18.4375 L 13.9375 18.625 C 16.261719 20.746094 19 21.90625 19 21.90625 L 19.625 22.1875 L 22.59375 19.21875 C 22.765625 19.046875 22.734375 19.046875 22.90625 19.21875 L 27 23.3125 C 27.171875 23.484375 27.171875 23.421875 27 23.59375 L 23.9375 26.65625 C 23.476563 27.050781 22.988281 27.132813 22.40625 26.9375 C 20.140625 26.046875 15.738281 24.113281 11.8125 20.1875 C 7.855469 16.230469 5.789063 11.742188 5.03125 9.5625 C 4.878906 9.15625 4.988281 8.554688 5.34375 8.25 L 5.40625 8.1875 L 8.4375 5.09375 C 8.507813 5.035156 8.582031 5 8.65625 5 Z"/></svg>
      </a>
      
      
      
      <a href="https://steamcommunity.com/id/enternity33/" title="steam" aria-label="steam">
        <svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="25" height="25"><path fill="currentColor" d="M 25 3 C 13.59 3 4.209375 11.680781 3.109375 22.800781 L 14.300781 28.529297 C 15.430781 27.579297 16.9 27 18.5 27 L 18.550781 27 C 18.940781 26.4 19.389375 25.649141 19.859375 24.869141 C 20.839375 23.259141 21.939531 21.439062 23.019531 20.039062 C 23.259531 15.569063 26.97 12 31.5 12 C 36.19 12 40 15.81 40 20.5 C 40 25.03 36.430937 28.740469 31.960938 28.980469 C 30.560938 30.060469 28.750859 31.160859 27.130859 32.130859 C 26.350859 32.610859 25.6 33.059219 25 33.449219 L 25 33.5 C 25 37.09 22.09 40 18.5 40 C 14.91 40 12 37.09 12 33.5 C 12 33.33 12.009531 33.17 12.019531 33 L 3.2792969 28.519531 C 4.9692969 38.999531 14.05 47 25 47 C 37.15 47 47 37.15 47 25 C 47 12.85 37.15 3 25 3 z M 31.5 14 C 27.92 14 25 16.92 25 20.5 C 25 24.08 27.92 27 31.5 27 C 35.08 27 38 24.08 38 20.5 C 38 16.92 35.08 14 31.5 14 z M 31.5 16 C 33.99 16 36 18.01 36 20.5 C 36 22.99 33.99 25 31.5 25 C 29.01 25 27 22.99 27 20.5 C 27 18.01 29.01 16 31.5 16 z M 18.5 29 C 17.71 29 16.960313 29.200312 16.320312 29.570312 L 19.640625 31.269531 C 20.870625 31.899531 21.350469 33.410625 20.730469 34.640625 C 20.280469 35.500625 19.41 36 18.5 36 C 18.11 36 17.729375 35.910469 17.359375 35.730469 L 14.029297 34.019531 C 14.289297 36.259531 16.19 38 18.5 38 C 20.99 38 23 35.99 23 33.5 C 23 31.01 20.99 29 18.5 29 z"/></svg>
      </a>
      
      
      
      
      
      <a href="https://www.zhihu.com/people/vigilr" title="zhihu" aria-label="zhihu">
        <svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="25" height="25"><path fill="currentColor" d="M 5.921875 2.9511719 C 5.5336094 2.9815469 5.1832344 3.2390625 5.0527344 3.6328125 L 3.6835938 7.7363281 C 3.5085938 8.2593281 3.7924062 8.825 4.3164062 9 C 4.8404063 9.175 5.4050781 8.8911875 5.5800781 8.3671875 L 6.0351562 7 L 6.9941406 7 L 6.9941406 10.222656 C 6.9941406 10.845846 6.9644144 11.431442 6.9199219 12 L 5 12 A 1.0001 1.0001 0 1 0 5 14 L 6.6367188 14 C 6.1575971 16.260332 5.1601574 17.989071 3.4179688 19.189453 C 2.9979688 19.479453 2.8798125 20.049188 3.1328125 20.492188 C 3.4258125 21.004188 4.0960781 21.153359 4.5800781 20.818359 C 6.0994455 19.769009 7.1700075 18.397613 7.8808594 16.720703 A 1.0001 1.0001 0 0 0 8.0449219 17.601562 L 9.5117188 19.59375 A 1.0002375 1.0002375 0 1 0 11.123047 18.408203 L 9.65625 16.416016 A 1.0001 1.0001 0 0 0 8.7929688 15.998047 A 1.0001 1.0001 0 0 0 7.9921875 16.472656 C 8.2917972 15.713486 8.5082238 14.883111 8.6699219 14 L 10 14 A 1.0001 1.0001 0 1 0 10 12 L 8.9316406 12 C 8.9726972 11.4285 8.9941406 10.836947 8.9941406 10.222656 L 8.9941406 7 L 10 7 A 1.0001 1.0001 0 1 0 10 5 L 6.7011719 5 L 6.9472656 4.2636719 C 7.1222656 3.7406719 6.8404063 3.175 6.3164062 3 C 6.1856563 2.95625 6.0512969 2.9410469 5.921875 2.9511719 z M 14 5 A 1.0001 1.0001 0 0 0 13 6 L 13 17 A 1.0001 1.0001 0 0 0 14 18 L 15 18 L 15 20 A 1.0001 1.0001 0 0 0 16.707031 20.707031 L 19.414062 18 L 21 18 A 1.0001 1.0001 0 0 0 22 17 L 22 6 A 1.0001 1.0001 0 0 0 21 5 L 14 5 z M 15 7 L 20 7 L 20 16 L 19 16 A 1.0001 1.0001 0 0 0 18.292969 16.292969 L 17 17.585938 L 17 17 A 1.0001 1.0001 0 0 0 16 16 L 15 16 L 15 7 z"/></svg>
      </a>
      
      
    </div>
  </div>
</section>
<hr class="hr-slash whoami-hr" />


    <section class="related">
    
    
  </section>
    <div class="grow"></div>
<nav class="pagination-single">
  
    
      <a href="https://eternidad33.gitee.io/zh/posts/%E7%A0%81%E4%BA%91%E4%B8%8A%E6%90%AD%E5%BB%BAhexo%E5%8D%9A%E5%AE%A2/" class="pagination-single__left">
        <div class="pagination-single__icon">
          <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path fill="currentColor" d="M19 11H7.83l4.88-4.88c.39-.39.39-1.03 0-1.42-.39-.39-1.02-.39-1.41 0l-6.59 6.59c-.39.39-.39 1.02 0 1.41l6.59 6.59c.39.39 1.02.39 1.41 0 .39-.39.39-1.02 0-1.41L7.83 13H19c.55 0 1-.45 1-1s-.45-1-1-1z"/></svg>
        </div>
        <div class="pagination-single__left-title">码云上搭建Hexo博客</div>      
      </a>
    
    <div class="grow"></div>
    
      <a href="https://eternidad33.gitee.io/zh/posts/hugo%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/" class="pagination-single__right">      
        <div class="pagination-single__right-title">Hugo博客搭建</div>
        <div class="pagination-single__icon">
          <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path fill="currentColor" d="M5 13h11.17l-4.88 4.88c-.39.39-.39 1.03 0 1.42.39.39 1.02.39 1.41 0l6.59-6.59c.39-.39.39-1.02 0-1.41l-6.58-6.6c-.39-.39-1.02-.39-1.41 0-.39.39-.39 1.02 0 1.41L16.17 11H5c-.55 0-1 .45-1 1s.45 1 1 1z"/></svg>
        </div>
      </a>
    
  
</nav>
    
  

    <div class="modal micromodal-slide" id="modal" aria-hidden="true">
  <div class="modal__overlay" tabindex="-1" data-micromodal-close>
    <div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="modal-title">
      
      <div class="modal__content" id="modal-content">
        <div id="mySwipe" class="swipe">
          <div class="swipe-wrap">
          </div>
        </div>
      </div>

      <span class="modal__items">
        
        <span class="modal__header">
          <div class="modal__paging" title="Page Info" aria-label="Current Page">
          </div>
          <div class="modal__icon modal__toolbar modal__toolbar--close" title="Close" aria-label="Close Button" data-micromodal-close>
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26" width="25" height="25"><path fill="currentColor" d="M 21.734375 19.640625 L 19.636719 21.734375 C 19.253906 22.121094 18.628906 22.121094 18.242188 21.734375 L 13 16.496094 L 7.761719 21.734375 C 7.375 22.121094 6.746094 22.121094 6.363281 21.734375 L 4.265625 19.640625 C 3.878906 19.253906 3.878906 18.628906 4.265625 18.242188 L 9.503906 13 L 4.265625 7.761719 C 3.882813 7.371094 3.882813 6.742188 4.265625 6.363281 L 6.363281 4.265625 C 6.746094 3.878906 7.375 3.878906 7.761719 4.265625 L 13 9.507813 L 18.242188 4.265625 C 18.628906 3.878906 19.257813 3.878906 19.636719 4.265625 L 21.734375 6.359375 C 22.121094 6.746094 22.121094 7.375 21.738281 7.761719 L 16.496094 13 L 21.734375 18.242188 C 22.121094 18.628906 22.121094 19.253906 21.734375 19.640625 Z"/></svg>
          </div>
          <div class="modal__icon modal__toolbar modal__toolbar--full" title="Full Screen" aria-label="Full Screen Button">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="25" height="25"><path fill="currentColor" d="M 5 3 C 3.9069372 3 3 3.9069372 3 5 L 3 8 A 1.0001 1.0001 0 1 0 5 8 L 5 5 L 8 5 A 1.0001 1.0001 0 1 0 8 3 L 5 3 z M 16 3 A 1.0001 1.0001 0 1 0 16 5 L 19 5 L 19 8 A 1.0001 1.0001 0 1 0 21 8 L 21 5 C 21 3.9069372 20.093063 3 19 3 L 16 3 z M 3.984375 14.986328 A 1.0001 1.0001 0 0 0 3 16 L 3 19 C 3 20.093063 3.9069372 21 5 21 L 8 21 A 1.0001 1.0001 0 1 0 8 19 L 5 19 L 5 16 A 1.0001 1.0001 0 0 0 3.984375 14.986328 z M 19.984375 14.986328 A 1.0001 1.0001 0 0 0 19 16 L 19 19 L 16 19 A 1.0001 1.0001 0 1 0 16 21 L 19 21 C 20.093063 21 21 20.093063 21 19 L 21 16 A 1.0001 1.0001 0 0 0 19.984375 14.986328 z"/></svg>
          </div>
          <div class="modal__icon modal__toolbar modal__toolbar--normal" title="Normal Screen" aria-label="Normal Screen Button">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="25" height="25"><path fill="currentColor" d="M 16.96875 4.972656 C 15.867188 4.988281 14.984375 5.894531 15 7 L 15 15 L 7 15 C 6.277344 14.988281 5.609375 15.367188 5.246094 15.992188 C 4.878906 16.613281 4.878906 17.386719 5.246094 18.007813 C 5.609375 18.632813 6.277344 19.011719 7 19 L 19 19 L 19 7 C 19.007813 6.460938 18.796875 5.941406 18.414063 5.558594 C 18.03125 5.175781 17.511719 4.964844 16.96875 4.972656 Z M 32.96875 4.972656 C 31.921875 4.988281 31.0625 5.8125 31.003906 6.859375 C 31 6.90625 31 6.953125 31 7 L 31 19 L 43 19 C 43.066406 19 43.132813 19 43.199219 18.992188 C 44.269531 18.894531 45.070313 17.972656 45.015625 16.902344 C 44.964844 15.828125 44.074219 14.988281 43 15 L 35 15 L 35 7 C 35.007813 6.460938 34.796875 5.941406 34.414063 5.558594 C 34.03125 5.175781 33.511719 4.964844 32.96875 4.972656 Z M 7 31 C 6.277344 30.988281 5.609375 31.367188 5.246094 31.992188 C 4.878906 32.613281 4.878906 33.386719 5.246094 34.007813 C 5.609375 34.632813 6.277344 35.011719 7 35 L 15 35 L 15 43 C 14.988281 43.722656 15.367188 44.390625 15.992188 44.753906 C 16.613281 45.121094 17.386719 45.121094 18.007813 44.753906 C 18.632813 44.390625 19.011719 43.722656 19 43 L 19 31 Z M 31 31 L 31 43 C 30.988281 43.722656 31.367188 44.390625 31.992188 44.753906 C 32.613281 45.121094 33.386719 45.121094 34.007813 44.753906 C 34.632813 44.390625 35.011719 43.722656 35 43 L 35 35 L 43 35 C 43.722656 35.011719 44.390625 34.632813 44.753906 34.007813 C 45.121094 33.386719 45.121094 32.613281 44.753906 31.992188 C 44.390625 31.367188 43.722656 30.988281 43 31 Z"/></svg>
          </div>
        </span>
        
        <div class="modal__icon modal__arrow modal__arrow--left" title="Arrow Left" aria-label="Arrow Left Button">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26" width="28" height="28"><path fill="currentColor" d="M 23.28125 11 L 10 10 L 10 6.851563 C 10 6.523438 9.839844 6.277344 9.519531 6.03125 C 9.199219 5.949219 8.878906 5.949219 8.640625 6.113281 C 5.359375 8.410156 2.238281 12.257813 2.160156 12.421875 C 2.082031 12.578125 2.007813 12.8125 2.003906 12.976563 C 2.003906 12.980469 2 12.988281 2 12.992188 C 2 13.15625 2.078125 13.402344 2.160156 13.484375 C 2.238281 13.648438 5.28125 17.507813 8.640625 19.804688 C 8.960938 19.96875 9.28125 20.050781 9.519531 19.886719 C 9.839844 19.722656 10 19.476563 10 19.148438 L 10 16 L 23.28125 15 C 23.679688 14.679688 24 13.875 24 12.992188 C 24 12.195313 23.761719 11.320313 23.28125 11 Z"/></svg>
        </div>
        
        <div class="modal__icon modal__arrow modal__arrow--right" title="Arrow Right" aria-label="Arrow Right Button">

          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26" width="28" height="28"><path fill="currentColor" d="M 2.71875 11.023438 L 16 10.023438 L 16 6.875 C 16 6.546875 16.160156 6.300781 16.480469 6.054688 C 16.800781 5.972656 17.121094 5.972656 17.359375 6.136719 C 20.640625 8.433594 23.761719 12.28125 23.839844 12.445313 C 23.917969 12.601563 23.992188 12.835938 23.996094 13 C 23.996094 13.003906 24 13.011719 24 13.015625 C 24 13.179688 23.921875 13.425781 23.839844 13.507813 C 23.761719 13.671875 20.71875 17.53125 17.359375 19.828125 C 17.039063 19.992188 16.71875 20.074219 16.480469 19.910156 C 16.160156 19.746094 16 19.5 16 19.171875 L 16 16.023438 L 2.71875 15.023438 C 2.320313 14.703125 2 13.898438 2 13.015625 C 2 12.21875 2.238281 11.34375 2.71875 11.023438 Z"/></svg>
        </div>

        <div class="modal__caption">
          <div class="modal__caption--text">
          </div>
        </div>

      </span>
    </div>
  </div>
</div>


<script defer src="/js/swipe.min.08ff2be1b74347bad9e267f732f1388d271b2f9d97b6a8a87bd6a510f17c5ad2.js"></script>

<script defer src="/js/micromodal.min.de01b44b2f383056bbcaf6ee921fd385d79108ec1129afd0eb2f3f5a07e11f45.js"></script>

<script defer src="/js/helper/fadeinout.min.js"></script>

<script>
document.addEventListener('DOMContentLoaded', function () {
  
   
  var docElem = document.documentElement;

   
  function openFullscreen() {
    if (docElem.requestFullscreen) {
      docElem.requestFullscreen();
    } else if (docElem.mozRequestFullScreen) {  
      docElem.mozRequestFullScreen();
    } else if (docElem.webkitRequestFullscreen) {  
      docElem.webkitRequestFullscreen();
    } else if (docElem.msRequestFullscreen) {  
      docElem.msRequestFullscreen();
    }
  }

   
  function closeFullscreen() {
    if (document.fullscreenElement ||
      document.webkitFullscreenElement ||
      document.mozFullScreenElement) {
      if (document.exitFullscreen) {
        document.exitFullscreen();
      } else if (document.mozCancelFullScreen) {  
        document.mozCancelFullScreen();
      } else if (document.webkitExitFullscreen) {  
        document.webkitExitFullscreen();
      } else if (document.msExitFullscreen) {  
        document.msExitFullscreen();
      }
    }
  }

  var modal = document.getElementById('modal');
  var galleryContainerElem = document.querySelector('.gallery__container');
  var swipeWrapElem = document.querySelector('.swipe-wrap');
  var mySwipeElem = document.getElementById('mySwipe');
  var arrowLeftElem = document.querySelector('.modal__arrow--left');
  var arrowRightElem = document.querySelector('.modal__arrow--right');
  var closeElem = document.querySelector('.modal__toolbar--close');
  var fullElem = document.querySelector('.modal__toolbar--full');
  var normalElem = document.querySelector('.modal__toolbar--normal');
  var captionElem = document.querySelector('.modal__caption');
  var pagingElem = document.querySelector('.modal__paging');
  var itemsElem = document.querySelector('.modal__items');
  var imgTotalNum = null;
  var myFadeTimeout = null;
  var mySwipe = null;
  var keydownFunction = function (e) {
    if (e.key === 'ArrowRight') {
      if (modal && modal.classList.contains('is-open')) {
        mySwipe.next();
      }
    } else if (e.key === 'ArrowLeft') {
      if (modal && modal.classList.contains('is-open')) {
        mySwipe.prev();
      }
    }
  }

  if (galleryContainerElem) {
    imgTotalNum = galleryContainerElem.querySelectorAll('img').length;
  } else {
    galleryContainerElem = document.querySelector('.single__contents');
    imgTotalNum = galleryContainerElem.querySelectorAll('img').length;
  }

  MicroModal.init({
    onClose: function () {
      if (mySwipe) {
        mySwipe.kill();
        mySwipe = null;
        closeFullscreen();
      }
      window.removeEventListener('keydown', keydownFunction);
    },
    disableScroll: true,
    disableFocus: true,
    awaitOpenAnimation: false,
    awaitCloseAnimation: false,
    debugMode: false,
  });

  var imageLoad = function(src) {
    return new Promise(function(resolve, reject) {
      var newImg = new Image;
      newImg.onload = function() {
        resolve(newImg);
      }
      newImg.onerror = reject;
      newImg.src = src;
    });
  }

  galleryContainerElem.querySelectorAll('img').forEach(function (elem, idx) {
    elem.style.cursor = 'pointer';

    var clonedElem = elem.cloneNode(true);
    clonedElem.style.maxHeight = '100%';
    clonedElem.style.maxWidth = '100%';
    clonedElem.onclick = function (e) {
      e.stopPropagation();
    }

    var wrapper = document.createElement('div');
    wrapper.style.width = '100%';
    wrapper.style.height = '100vh';
    wrapper.setAttribute('data-micromodal-close', '');
    wrapper.onclick = function () {
      if (mySwipe) {
        mySwipe.kill();
        mySwipe = null;
      }
    }
    wrapper.onmouseenter = function () {
      clearTimeout(myFadeTimeout);
      fadeIn(itemsElem, 200);
    };
    wrapper.onmouseleave = function () {
      myFadeTimeout = setTimeout(function () {
        fadeOut(itemsElem, 200);
      }, 2500);
    }
    wrapper.ontouchstart = function() {
      fadeIn(itemsElem, 200);
    }
    wrapper.append(clonedElem);
    swipeWrapElem.append(wrapper);

    elem.addEventListener('click', async function (e) {
      MicroModal.show('modal');
      if (mySwipe) {
        mySwipe.kill();
        mySwipe = null;
      }

      var imgSrc = e.target.getAttribute('data-src') || e.target.getAttribute('src');
      var img = await imageLoad(imgSrc);
      clonedElem.style.width = img.width + 'px';
      clonedElem.style.height = img.height + 'px';
      
      
      mySwipe = new Swipe(mySwipeElem, {
        startSlide: idx,
        draggable: true,
        autoRestart: false,
        continuous: false,
        disableScroll: true,
        stopPropagation: true,
        callback: async function (index, element) {
          
          var imgElem = element.querySelector('img');
          var imgSrc = imgElem.getAttribute('data-src') || imgElem.getAttribute('src');
          var img = await imageLoad(imgSrc);
          imgElem.style.width = img.width + 'px';
          imgElem.style.height = img.height + 'px';

          
          if (captionElem && imgElem) {
            var caption = null;
            if (imgElem.getAttribute('data-caption')) {
              caption = imgElem.getAttribute('data-caption');
            } else if (imgElem.getAttribute('title')) {
              caption = imgElem.getAttribute('title');
            } else if (imgElem.getAttribute('alt')) {
              caption = imgElem.getAttribute('alt');
            } else {
              caption = imgElem.getAttribute('src');
            }

            captionElem.querySelector('.modal__caption--text').innerText = caption;
            pagingElem.innerText = (index + 1) + ' / ' + imgTotalNum;

            clearTimeout(myFadeTimeout);
            fadeIn(itemsElem, 200);
          }
        },
      });

      fadeIn(itemsElem);

      
      if (captionElem) {
        var caption = null;
        if (e.target.getAttribute('data-caption')) {
          caption = e.target.getAttribute('data-caption');
        } else if (e.target.getAttribute('title')) {
          caption = e.target.getAttribute('title');
        } else if (e.target.getAttribute('alt')) {
          caption = e.target.getAttribute('alt');
        } else {
          caption = e.target.getAttribute('src');
        }

        captionElem.querySelector('.modal__caption--text').innerText = caption;
        pagingElem.innerText = (idx + 1) + ' / ' + imgTotalNum;
      }

      if (normalElem && fullElem) {
        normalElem.style.zIndex = -1;
        normalElem.style.opacity = 0;
        fullElem.style.zIndex = 25;
        fullElem.style.opacity = 1;
      }
    });

    window.addEventListener('keydown', keydownFunction);
  });

  arrowLeftElem ?
    arrowLeftElem.addEventListener('click', function (e) {
      if (mySwipe) {
        mySwipe.prev();
      }
    }) : null;
  arrowRightElem ?
    arrowRightElem.addEventListener('click', function (e) {
      if (mySwipe) {
        mySwipe.next();
      }
    }) : null;

  closeElem ?
    closeElem.addEventListener('click', function () {
      if (mySwipe) {
        mySwipe.kill();
        mySwipe = null;
      }
      closeFullscreen();
      MicroModal.close('modal');
    }) : null;

  fullElem ?
    fullElem.addEventListener('click', function (e) {
      openFullscreen();
      if (normalElem) {
        normalElem.style.zIndex = 25;
        normalElem.style.opacity = 1;
        fullElem.style.zIndex = -1;
        fullElem.style.opacity = 0;
      }
    }) : null;

  normalElem ?
    normalElem.addEventListener('click', function (e) {
      closeFullscreen();
      if (fullElem) {
        fullElem.style.zIndex = 25;
        fullElem.style.opacity = 1;
        normalElem.style.zIndex = -1;
        normalElem.style.opacity = 0;
      }
    }) : null;
  
});
</script>

    <div class="hide">
      

<div class="search">
  <span class="icon">
    <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="currentColor" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M15.5 14h-.79l-.28-.27c1.2-1.4 1.82-3.31 1.48-5.34-.47-2.78-2.79-5-5.59-5.34-4.23-.52-7.79 3.04-7.27 7.27.34 2.8 2.56 5.12 5.34 5.59 2.03.34 3.94-.28 5.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>
  </span>
  <input id="search" aria-label="Site Search" class="input" type="text" placeholder="搜索" autocomplete="off">
  <div id="search-results" class="dropdown">
    <div id="search-menu" class="dropdown-menu" role="menu">
    </div>
  </div>
</div>


    </div>
  </div>
</main>


<aside class="single__side main-side">
  


<section class="sidebar hide">
  <script>document.querySelector('.sidebar').classList.remove('hide')</script>
  <div class="toc__flexbox" data-position="fixed">
    <h6 class="toc__title" data-ani="true">目录</h6>
    
      <label class="switch" data-ani="true">
        <input id="toggle-toc" aria-label="Toggle TOC" type="checkbox" checked>
        <span class="slider round"></span>
      </label>
    
  </div>
  <div class="toc " data-dir="ltr" data-folding="true" data-ani="true">
    <nav id="TableOfContents">
  <ul>
    <li>
      <ul>
        <li><a href="#java-基础">Java 基础</a></li>
        <li><a href="#数组">数组</a></li>
        <li><a href="#string">String</a></li>
        <li><a href="#面向对象">面向对象</a>
          <ul>
            <li><a href="#继承">继承</a></li>
            <li><a href="#多态">多态</a></li>
            <li><a href="#object-类">Object 类</a></li>
            <li><a href="#抽象类">抽象类</a></li>
            <li><a href="#包装类">包装类</a></li>
            <li><a href="#接口">接口</a></li>
          </ul>
        </li>
        <li><a href="#设计模式">设计模式</a></li>
        <li><a href="#泛型">泛型</a></li>
        <li><a href="#包">包</a></li>
        <li><a href="#uml">UML</a></li>
        <li><a href="#枚举">枚举</a></li>
        <li><a href="#异常">异常</a></li>
        <li><a href="#内部类">内部类</a></li>
        <li><a href="#函数式编程">函数式编程</a></li>
        <li><a href="#链表">链表</a></li>
        <li><a href="#awt">AWT</a></li>
        <li><a href="#正则表达式">正则表达式</a></li>
        <li><a href="#list-集合">List 集合</a></li>
        <li><a href="#set-集合">Set 集合</a></li>
        <li><a href="#map-集合">Map 集合</a></li>
        <li><a href="#java-多线程编程">Java 多线程编程</a>
          <ul>
            <li><a href="#thread-与-runnable-关系">Thread 与 Runnable 关系</a></li>
            <li><a href="#线程常用操作方法">线程常用操作方法</a></li>
            <li><a href="#线程的同步与死锁">线程的同步与死锁</a></li>
          </ul>
        </li>
        <li><a href="#基础类库">基础类库</a></li>
        <li><a href="#比较器">比较器</a></li>
        <li><a href="#红黑树原理">红黑树原理</a></li>
        <li><a href="#文件操作">文件操作</a></li>
        <li><a href="#字节流与字符流">字节流与字符流</a></li>
        <li><a href="#io-操作深入">IO 操作深入</a></li>
        <li><a href="#输入与输出支持">输入与输出支持</a></li>
        <li><a href="#对象序列化">对象序列化</a></li>
        <li><a href="#反射机制">反射机制</a></li>
        <li><a href="#集合工具类">集合工具类</a></li>
        <li><a href="#stream-数据流">Stream 数据流</a></li>
        <li><a href="#网络编程">网络编程</a></li>
        <li><a href="#jdbc">JDBC</a></li>
      </ul>
    </li>
  </ul>
</nav>
  </div>
</section>



</aside>

<script>
  
  
  

  var enableToc = JSON.parse("true");
  var toc = JSON.parse("null");
  var tocPosition = JSON.parse("\"inner\"");
  
  var singleMainElem = document.querySelector('.single__main');
  var singleSideElem = document.querySelector('.single__side');

  enquire.register("screen and (max-width: 769px)", {
    match: function () {
      if ((enableToc || toc) && tocPosition !== "outer") {
        if (singleMainElem && singleSideElem) {
          singleMainElem.classList.remove('main-main');
          singleMainElem.classList.add('main');
          singleSideElem.classList.remove('main-side');
          singleSideElem.classList.add('hide');
        }
      } else if (tocPosition === "outer") {
        if (singleMainElem && !singleMainElem.classList.contains('main-main')) {
          singleMainElem.classList.remove('main-main');
          singleMainElem.classList.add('main');
        }
        if (singleSideElem && !singleSideElem.classList.contains('hide')) {
          singleSideElem.classList.add('hide');
        }
      }
    },
    unmatch: function () {
      if ((enableToc || toc) && tocPosition !== "outer") {
        singleMainElem.classList.remove('main');
        singleMainElem.classList.add('main-main');
        singleSideElem.classList.remove('hide');
        singleSideElem.classList.add('main-side');
      } else if (tocPosition === "outer") {
        if (singleMainElem && !singleMainElem.classList.contains('main-main')) {
          singleMainElem.classList.remove('main-main');
          singleMainElem.classList.add('main');
        }
        if (singleSideElem && !singleSideElem.classList.contains('hide')) {
          singleSideElem.classList.add('hide');
        }
      }

      var navCollapseBtn = document.querySelector('.navbar__burger');
      var navCollapse = document.getElementsByClassName('navbarm__collapse')[0];
      if (navCollapse) {
        navCollapse.setAttribute('data-open', false);
        navCollapse.style.maxHeight = 0;
        navCollapseBtn.classList.remove('is-active');
      }
      document.getElementsByClassName('navbar__menu')[0].classList.remove('is-active');
      document.getElementsByClassName('mobile-search')[0].classList.add('hide');
    },
    setup: function () { },
    deferSetup: true,
    destroy: function () { },
  });
</script>




<script defer src="/js/clipboard.min.c168d3a04c45a631be76437054619a4a3b30107960cb9730be96012fef5762b0.js"></script>

<script defer src="/js/helper/getParents.min.js"></script>

<script defer src="/js/helper/closest.min.js"></script>

<script defer src="/js/helper/prev.min.js"></script>

<script defer src="/js/helper/prop.min.js"></script>

<script defer src="/js/helper/fadeinout.min.js"></script>

















<script>
  'use strict';

  window.onload = function() {
    var navbar = document.querySelector('.navbar');
    var singleContentsElem = document.querySelector('.single__contents');

    
    
    
    var enableBusuanzi = JSON.parse("false");
    var busuanziPagePV = JSON.parse("true");
    
    if (enableBusuanzi && busuanziPagePV) {
      var pagePvElem = document.querySelector('#busuanzi_value_page_pv');
      pagePvElem.textContent = pagePvElem.textContent.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
    }    
    


    
    
    
    
    
    
    var enableToc = JSON.parse("true");
    var toc = JSON.parse("null");
    var hideToc = JSON.parse("false");
    var tocFlexbox = document.querySelector('.toc__flexbox');
    var tocFlexboxOuter = document.querySelector('.toc__flexbox--outer');
    var tocFolding = JSON.parse("true");
    
    if ((enableToc || toc) && document.querySelector('.toc')) {
      var tableOfContentsElem = document.querySelector('.toc').querySelector('#TableOfContents');

      if (false === tocFolding) {

      } else {
        tableOfContentsElem.querySelectorAll('ul') ?
          tableOfContentsElem.querySelectorAll('ul').forEach(function (rootUl) {
            rootUl.querySelectorAll('li').forEach(function (liElem) {
              liElem.querySelectorAll('ul').forEach(function (ulElem) {
                ulElem.style.display = 'none';
              });
            });
          }) : null;
      }

      if (tableOfContentsElem) {
        if (tableOfContentsElem.querySelectorAll('a').length > 0) {
          tableOfContentsElem.querySelectorAll('a').forEach(function (elem) {
            elem.addEventListener('click', function () {
              var id = elem.getAttribute('id');
              navbar.classList.remove('navbar--show');
              navbar.classList.remove('navbar--hide');
              navbar.classList.add('navbar--hide');

              document.querySelector('.toc').querySelectorAll('a').forEach(function (elem) {
                elem.classList.remove('active');
              });
              elem.classList.add('active');

              var curElem = tableOfContentsElem.querySelector('[href="#' + id + '"]');
              if (curElem && curElem.nextElementSibling) {
                curElem.nextElementSibling.style.display = 'block';
              }
              if (curElem) {
                getParents(curElem, 'ul') ?
                  getParents(curElem, 'ul').forEach(function (elem) {
                    elem.style.display = 'block';
                  }) : null;
              }
            });
          });
        } else {
          if (tocFlexbox) {
            tocFlexbox.setAttribute('data-position', '');
            if (!tocFlexbox.classList.contains('hide')) {
              tocFlexbox.classList.add('hide');
            }
          }
          if (tocFlexboxOuter) {
            tocFlexboxOuter.setAttribute('data-position', '');
            if (!tocFlexboxOuter.classList.contains('hide')) {
              tocFlexboxOuter.classList.add('hide');
            }
          }
        }
      }

      
      var toggleTocElem = document.getElementById("toggle-toc");
      var visibleTocElem = document.getElementById('visible-toc');
      var tocElem = document.querySelector('.toc');
      var mainElem = document.querySelector('main');
      var sideElem = document.querySelector('side');
      var tocFlexboxElem = document.querySelector('.toc__flexbox');

      toggleTocElem ? 
      toggleTocElem.addEventListener('change', function(e) {
        if (e.target.checked) {
          if (tocElem) {
            fadeIn(tocElem, 200);
          }
          if (tocFlexboxElem) {
            tocFlexboxElem.setAttribute('data-position', 'fixed');
          }

          if (mainElem) {
            mainElem.classList.remove('main-main');
            mainElem.classList.remove('main');
            mainElem.classList.add('main-main');
          }
          if (sideElem) {
            sideElem.classList.remove('main-side');
          }
        } else {
          if (tocElem) {
            fadeOut(tocElem, 200);
          }
          if (tocFlexboxElem) {
            tocFlexboxElem.setAttribute('data-position', 'absolute');
          }

          if (mainElem) {
            mainElem.classList.remove('main-main');
            mainElem.classList.remove('main');
            mainElem.classList.add('main');
          }
          if (sideElem) {
            sideElem.classList.remove('main-side');
          }
        }
      }) : null;

      visibleTocElem ?
      visibleTocElem.addEventListener('change', function(e) {
        if (e.target.checked) {
          if (tocElem) {
            fadeIn(tocElem, 200);
          }
        } else {
          if (tocElem) {
            fadeOut(tocElem, 200);
          }
        }
      }) : null;
    }
    


    
    var tables = document.querySelectorAll('.single__contents > table');
    for (let i = 0; i < tables.length; i++) {
      var table = tables[i];
      var wrapper = document.createElement('div');
      wrapper.className = 'table-wrapper';
      table.parentElement.replaceChild(wrapper, table);
      wrapper.appendChild(table);
    }
    


    
    var text, clip = new ClipboardJS('.anchor');
    var headers = singleContentsElem.querySelectorAll("h1, h2, h3, h4");

    
    var languagedir = JSON.parse("\"ltr\"");

    headers ? 
    headers.forEach(function (elem) {
      var url = encodeURI(document.location.origin + document.location.pathname);
      var link = url + "#" + elem.getAttribute('id');
      var newElemOuter = document.createElement('span');
      newElemOuter.classList.add('anchor');
      newElemOuter.classList.add('hide');
      newElemOuter.setAttribute('data-clipboard-text', link);
      newElemOuter.style.position = 'relative';

      var newElemInner = document.createElement('span');
      newElemInner.style.fontSize = '1rem';
      newElemInner.style.position = 'absolute';
      newElemInner.style.top = '50%';
      newElemInner.style.transform = 'translateY(-50%)';
      newElemInner.innerText = "🔗";

      if (languagedir === "rtl") {
        newElemInner.style.left = '-2rem';
      } else {
        newElemInner.style.right = '-2rem';
      }

      newElemOuter.append(newElemInner);
      elem.append(newElemOuter);

      elem.addEventListener('mouseenter', function() {
        this.querySelector('.anchor').classList.remove('hide');
      });
      elem.addEventListener('mouseleave', function () {
        this.querySelector('.anchor').classList.add('hide');
      });
    }) : null;

    document.querySelectorAll('.anchor').forEach(function(elem) {
      elem.addEventListener('mouseleave', function() {
        elem.setAttribute('aria-label', null);
        elem.classList.remove('tooltipped');
        elem.classList.remove('tooltipped-s');
        elem.classList.remove('tooltipped-w');
      });
    });

    clip.on('success', function (e) {
      e.clearSelection();
      e.trigger.setAttribute('aria-label', 'Link copied to clipboard!');
      e.trigger.classList.add('tooltipped');
      e.trigger.classList.add('tooltipped-s');
    });
    


    
    var clipInit = false;
    var preChromaElem = document.querySelectorAll('pre.chroma');
    var langCodeElem = document.querySelectorAll('.language-code');
    var dollarCodeElem = document.querySelectorAll('div.language-\\$');
    var gtCodeElem = document.querySelectorAll('div.language-\\>');

    var makeClipboard = function(elem) {
      var code = elem,
        text = elem.textContent;
        
      if (text.length > 15) {
        if (!clipInit) {
          var text, clip = new ClipboardJS('.copy-to-clipboard', {
            text: function (trigger) {
              var codeElem = prev(trigger).querySelectorAll('code');
              if (codeElem.length > 1) {
                text = prev(trigger).querySelector('code[class^="language-"]').textContent;
              } else {
                text = prev(trigger).querySelector('code').textContent;
              }

              return text.replace(/^\$\s/gm, '');
            }
          });

          var inPre;
          clip.on('success', function (e) {
            e.clearSelection();
            inPre = prop(e.trigger.parentNode, 'tagName') == 'PRE';
            e.trigger.setAttribute('aria-label', 'Copied to clipboard!');
            e.trigger.classList.add('tooltipped');
            e.trigger.classList.add('tooltipped-w');
          });

          clip.on('error', function (e) {
            inPre = prop(e.trigger.parentNode, 'tagName') == 'PRE';
            e.trigger.setAttribute('aria-label', e.action.toString());
            e.trigger.classList.add('tooltipped');
            e.trigger.classList.add('tooltipped-w');
          });

          clipInit = true;
        }

        var notAllowedClass = ['language-mermaid', 'language-viz', 'language-wave', 'language-chart', 'language-msc', 'language-flowchart'];
        var isNotAllowedIncluded = false;
        var curClassName = code.getAttribute('class');

        for (var i = 0; i < notAllowedClass.length; i++) {
          if (curClassName && curClassName.startsWith(notAllowedClass[i])) {
            isNotAllowedIncluded = true;
            break;
          }
        }

        if (!isNotAllowedIncluded) {
          if (curClassName) {
            var newClipboardElem = document.createElement('span');
            newClipboardElem.setAttribute('class', 'copy-to-clipboard');
            newClipboardElem.setAttribute('title', 'Copy to clipboard');
            elem.parentNode.parentNode.insertBefore(newClipboardElem, elem.parentNode.nextElementSibling);
          }
        }
      }
    }

    var makeSymbolClipboard = function(elem) {
      var clipboardSpan = document.createElement('span');
      clipboardSpan.setAttribute('class', 'copy-to-clipboard');
      clipboardSpan.setAttribute('title', 'Copy to clipboard');
      elem.parentNode.parentNode.insertBefore(clipboardSpan, elem.parentNode.nextElementSibling);
    }

    preChromaElem ? 
    preChromaElem.forEach(function(elem) {
      elem.querySelectorAll('code').forEach(function(codeElem) {
        makeClipboard(codeElem);
      });
    }) : null;
    
    langCodeElem ? 
    langCodeElem.forEach(function(elem) {
      elem.querySelectorAll('code').forEach(function (codeElem) {
        makeClipboard(codeElem);
      });
    }) : null;

    dollarCodeElem ? 
    dollarCodeElem.forEach(function(elem) {
      elem.querySelectorAll('code').forEach(function (codeElem) {
        makeSymbolClipboard(codeElem);
      });
    }) : null;

    gtCodeElem ?
    gtCodeElem.forEach(function(elem) {
      elem.querySelectorAll('code').forEach(function (codeElem) {
        makeSymbolClipboard(codeElem);
      });
    }) : null;
    


    
    dollarCodeElem ?
    dollarCodeElem.forEach(function(elem) {
      var lnts = elem.parentNode.parentNode ? elem.parentNode.parentNode.querySelectorAll('.lnt') : null;
      lnts ? 
      lnts.forEach(function(lnt) {
        lnt.innerHTML = '$<br/>';
      }) : null;
    }) : null;

    gtCodeElem ?
    gtCodeElem.forEach(function(elem) {
      var lnts = elem.parentNode.parentNode ? elem.parentNode.parentNode.querySelectorAll('.lnt') : null;
      lnts ? 
      lnts.forEach(function(lnt) {
        lnt.innerHTML = '><br/>';
      }) : null;
    }) : null;
    


    
    
    var lib = JSON.parse("null");

    if (lib && lib.includes('mermaid')) {
      
      var themeVariant = localStorage.getItem('theme') || JSON.parse("\"dark\"");

      if (themeVariant === "dark" || themeVariant === "hacker") {
        mermaid.initialize({ theme: 'dark' });
      } else {
        mermaid.initialize({ theme: 'default' });
      }
      
      var mermaids = [];
      [].push.apply(mermaids, document.getElementsByClassName('language-mermaid'));
      mermaids.forEach(function(elem) {
        var elemParentNode = elem.parentNode;

        if (elemParentNode !== document.body) {
          elemParentNode.parentNode.insertBefore(elem, elemParentNode);
          elemParentNode.parentNode.removeChild(elemParentNode);
        }

        var newElemWrapper = document.createElement('div');
        newElemWrapper.classList.add('mermaid');
        newElemWrapper.style.padding = '34px 4px 6px';
        newElemWrapper.innerHTML = elem.innerHTML;
        elem.replaceWith(newElemWrapper);
      });
    }
    
    

    
    if (lib && lib.includes('katex')) {
      var mathElements = document.getElementsByClassName('math');
      var options = {
        delimiters: [
          { left: "$$", right: "$$", display: true },
          { left: "\\[", right: "\\]", display: true },
          { left: "$", right: "$", display: false },
          { left: "\\(", right: "\\)", display: false }
        ],
      };

      renderMathInElement(document.querySelector('.single__contents'), options);
    }
    


    
    if (lib && lib.includes('flowchartjs')) {
      
      var options = JSON.parse("{\"arrow-end\":\"block\",\"element-color\":\"black\",\"fill\":\"white\",\"flowstate\":{\"approved\":{\"fill\":\"#58C4A3\",\"font-size\":12,\"no-text\":\"n/a\",\"yes-text\":\"APPROVED\"},\"current\":{\"fill\":\"yellow\",\"font-color\":\"red\",\"font-weight\":\"bold\"},\"future\":{\"fill\":\"#FFFF99\"},\"invalid\":{\"fill\":\"#444444\"},\"past\":{\"fill\":\"#CCCCCC\",\"font-size\":12},\"rejected\":{\"fill\":\"#C45879\",\"font-size\":12,\"no-text\":\"REJECTED\",\"yes-text\":\"n/a\"},\"request\":{\"fill\":\"blue\"}},\"font-color\":\"black\",\"font-size\":14,\"line-color\":\"black\",\"line-length\":50,\"line-width\":3,\"no-text\":\"no\",\"scale\":1,\"symbols\":{\"end\":{\"class\":\"end-element\"},\"start\":{\"element-color\":\"green\",\"fill\":\"yellow\",\"font-color\":\"red\"}},\"text-margin\":10,\"x\":0,\"y\":0,\"yes-text\":\"yes\"}");
      var jsonContent = null;

      var flowchartPrefix = "language-flowchart";
      var index = 0;
      Array.prototype.forEach.call(document.querySelectorAll("[class^=" + flowchartPrefix + "]"), function(x){
          x.style.display = 'none'
          x.parentNode.style.backgroundColor = "transparent"
          jsonContent = x.innerText;

          var node0 = document.createElement('div');
          node0.id = 'flowchart' + index;
          x.parentNode.insertBefore(node0, x);

          var diagram = flowchart.parse(jsonContent);
          diagram.drawSVG("flowchart"+index, options);

          index +=1;
      });      
    }
    


    
    


    
    if (lib && lib.includes('msc')) {
      
      var options = JSON.parse("{\"theme\":\"hand\"}");
      var jsonContent = null;

      var index = 0;
      var chartPrefix = "language-msc";
      Array.prototype.forEach.call(document.querySelectorAll("[class^=" + chartPrefix + "]"), function (x) {
        x.style.display = 'none'
        x.parentNode.style.backgroundColor = "transparent"
        jsonContent = x.innerText;
        var node0 = document.createElement('div');
        node0.id = 'msc' + index;
        x.parentNode.insertBefore(node0, x);
        var diagram = Diagram.parse(jsonContent);
        diagram.drawSVG("msc" + index, options);
        index += 1;
      });
    }
    


    
    if (lib && lib.includes('chart')) {
      var borderColor = "#666";
      var bgColor = "#ddd";
      var borderWidth = 2;

      Chart.defaults.global.elements.rectangle.borderWidth = borderWidth;
      Chart.defaults.global.elements.rectangle.borderColor = borderColor;
      Chart.defaults.global.elements.rectangle.backgroundColor = bgColor;

      Chart.defaults.global.elements.line.borderWidth = borderWidth;
      Chart.defaults.global.elements.line.borderColor = borderColor;
      Chart.defaults.global.elements.line.backgroundColor = bgColor;

      Chart.defaults.global.elements.point.borderWidth = borderWidth;
      Chart.defaults.global.elements.point.borderColor = borderColor;
      Chart.defaults.global.elements.point.backgroundColor = bgColor;

      var chartPrefix = "language-chart";
      var index = 0;
      var jsonContent = null;

      Array.prototype.forEach.call(document.querySelectorAll("[class^=" + chartPrefix + "]"), function (x) {
        x.style.display = 'none'
        x.parentNode.style.backgroundColor = "transparent"
        jsonContent = x.innerText;
        var node0 = document.createElement('canvas');
        var source = null;
        node0.height = 200;
        node0.style.height = 200;
        node0.id = 'myChart' + index;
        source = JSON.parse(jsonContent);
        x.parentNode.insertBefore(node0, x);
        var ctx = document.getElementById('myChart' + index).getContext('2d');
        var myChart = new Chart(ctx, source);
        index += 1;
      });            
    }
    


    
    if (lib && lib.includes('wavedrom')) {
      var wavePrefix = "language-wave";
      var index = 0;
      var jsonContent = null;
      
      Array.prototype.forEach.call(document.querySelectorAll("[class^=" + wavePrefix + "]"), function (x) {
        x.style.display = 'none'
        x.parentNode.style.backgroundColor = "transparent"
        jsonContent = x.innerText;
        var node0 = document.createElement('div');
        var source = null;
        node0.id = 'WaveDrom_Display_' + index;
        source = JSON.parse(jsonContent);
        x.parentNode.insertBefore(node0, x);
        WaveDrom.RenderWaveForm(index, source, "WaveDrom_Display_");
        index += 1;
      });
    }
    


    
    if (lib && lib.includes('viz')) {
      var vizPrefix = "language-viz-";
      Array.prototype.forEach.call(document.querySelectorAll("[class^=" + vizPrefix + "]"), function (x) {
        x.style.display = 'none'
        x.parentNode.style.backgroundColor = "transparent"
        var engine;
        x.getAttribute("class").split(" ").forEach(function (cls) {
          if (cls.startsWith(vizPrefix)) {
            engine = cls.substr(vizPrefix.length);
          }
        });
        var viz = new Viz();
        viz.renderSVGElement(x.innerText, { engine: engine })
          .then(function (element) {
            element.style.width = "100%";
            x.parentNode.insertBefore(element, x);
          })
      });
    }
    
    
  }
</script>


            
            <footer class="footer">
    
<div class="dropdown">
  <button class="dropdown-trigger" aria-label="Select Theme Button">
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path fill="currentColor" d="M12.65 15.67c.14-.36.05-.77-.23-1.05l-2.09-2.06.03-.03c1.74-1.94 2.98-4.17 3.71-6.53h1.94c.54 0 .99-.45.99-.99v-.02c0-.54-.45-.99-.99-.99H10V3c0-.55-.45-1-1-1s-1 .45-1 1v1H1.99c-.54 0-.99.45-.99.99 0 .55.45.99.99.99h10.18C11.5 7.92 10.44 9.75 9 11.35c-.81-.89-1.49-1.86-2.06-2.88-.16-.29-.45-.47-.78-.47-.69 0-1.13.75-.79 1.35.63 1.13 1.4 2.21 2.3 3.21L3.3 16.87c-.4.39-.4 1.03 0 1.42.39.39 1.02.39 1.42 0L9 14l2.02 2.02c.51.51 1.38.32 1.63-.35zM17.5 10c-.6 0-1.14.37-1.35.94l-3.67 9.8c-.24.61.22 1.26.87 1.26.39 0 .74-.24.88-.61l.89-2.39h4.75l.9 2.39c.14.36.49.61.88.61.65 0 1.11-.65.88-1.26l-3.67-9.8c-.22-.57-.76-.94-1.36-.94zm-1.62 7l1.62-4.33L19.12 17h-3.24z"/></svg>
  </button>
  <div class="dropdown-content">
    
    
    
      
      
        
      
        
        
          
            
              <a href="https://eternidad33.gitee.io/zh/posts/java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" data-lang="zh" class="dropdown-item is-active">简体中文</a>
            
          
        
      
    
  </div>
</div>

    
<div class="footer__social">
  <div class="social">
    
      
      <a href="https://blog.csdn.net/qq_42907802" title="csdn" aria-label="csdn">
        <svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32"><path fill="currentColor" d="M11.705 9.681l-.03.247c-.035.288-.3.484-.585.439-.47-.081-1.135-.151-1.64-.151-.765 0-1.16.267-1.19.56-.035.368.365.389 1.355.681 1.345.378 1.935.913 1.855 1.741C11.38 14.172 10.31 15 8.165 15c-.655 0-1.24-.096-1.675-.222-.24-.066-.395-.293-.37-.545l.035-.288c.045-.232.25-.404.49-.404.035 0 .065.005.095.01.01 0 1.057.237 1.61.202.808-.051 1.26-.247 1.3-.636.03-.353-.3-.404-1.22-.646-1.265-.343-2.075-.878-1.995-1.731C6.53 9.752 7.72 9 9.555 9 10.2 9 10.83 9.035 11.3 9.121 11.56 9.167 11.74 9.414 11.705 9.681zM18.79 9.814c.019-.223.184-.409.404-.45 4.533-.849 4.929.926 4.782 2.502l-.241 2.54c-.024.257-.24.453-.498.453h-.546c-.295 0-.526-.254-.498-.547l.207-2.182c.056-.601.405-1.776-1.281-1.732-.186.005-.343.017-.469.032-.235.027-.414.218-.433.455-.021.255-.05.595-.083.88l-.251 2.642c-.024.257-.24.453-.498.453h-.514c-.296 0-.527-.255-.498-.549l.247-2.501L18.79 9.814zM17.115 9.846c-.615-.5-1.611-.696-2.84-.735-.531-.017-1.087.024-1.265.05-.192.029-.345.19-.385.38-.01.035-.015.07-.015.11l-.43 4.635c-.03.275.17.52.44.545.425.045.91.065 1.41.065 1.205 0 2.005-.18 2.64-.59.695-.44 1.17-1.15 1.265-2.16C18.035 11.056 17.665 10.306 17.115 9.846zM16.435 12.106c-.085.935-.955 1.605-2.185 1.605-.305 0-.46-.025-.58-.05l.3-3.355c.125-.025.36-.025.525-.025C15.795 10.271 16.565 10.746 16.435 12.106zM5.367 14.461c-.021.227-.19.41-.415.448C4.623 14.966 4.163 15 3.595 15c-2.427 0-3.737-1.254-3.583-2.913C.198 10.112 2.139 9 4.264 9c.559 0 .961.034 1.304.093.259.045.437.286.408.547L5.941 9.965c-.031.283-.292.487-.573.439-.326-.055-.724-.093-1.071-.093-1.25 0-2.312.41-2.434 1.707-.109 1.16.637 1.714 2.044 1.714.271 0 .614-.024.922-.064.318-.041.592.222.562.541L5.367 14.461z"/></svg>
      </a>
            
    
            
    
      
      <a href="mailto:tfl2020@foxmail.com" title="email" aria-label="email">
        <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path fill="currentColor" d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-.4 4.25l-7.07 4.42c-.32.2-.74.2-1.06 0L4.4 8.25c-.25-.16-.4-.43-.4-.72 0-.67.73-1.07 1.3-.72L12 11l6.7-4.19c.57-.35 1.3.05 1.3.72 0 .29-.15.56-.4.72z"/></svg>
      </a>
            
    
      
      <a href="https://github.com/eternidad33/" title="github" aria-label="github">
        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 24 24" version="1.1">
<g id="surface3680">
<path fill="currentColor" d="M 10.898438 2.101562 C 6.300781 2.601562 2.601562 6.300781 2.101562 10.800781 C 1.601562 15.5 4.300781 19.699219 8.398438 21.300781 C 8.699219 21.398438 9 21.199219 9 20.800781 L 9 19.199219 C 9 19.199219 8.601562 19.300781 8.101562 19.300781 C 6.699219 19.300781 6.101562 18.101562 6 17.398438 C 5.898438 17 5.699219 16.699219 5.398438 16.398438 C 5.101562 16.300781 5 16.300781 5 16.199219 C 5 16 5.300781 16 5.398438 16 C 6 16 6.5 16.699219 6.699219 17 C 7.199219 17.800781 7.800781 18 8.101562 18 C 8.5 18 8.800781 17.898438 9 17.800781 C 9.101562 17.101562 9.398438 16.398438 10 16 C 7.699219 15.5 6 14.199219 6 12 C 6 10.898438 6.5 9.800781 7.199219 9 C 7.101562 8.800781 7 8.300781 7 7.601562 C 7 7.199219 7 6.601562 7.300781 6 C 7.300781 6 8.699219 6 10.101562 7.300781 C 10.601562 7.101562 11.300781 7 12 7 C 12.699219 7 13.398438 7.101562 14 7.300781 C 15.300781 6 16.800781 6 16.800781 6 C 17 6.601562 17 7.199219 17 7.601562 C 17 8.398438 16.898438 8.800781 16.800781 9 C 17.5 9.800781 18 10.800781 18 12 C 18 14.199219 16.300781 15.5 14 16 C 14.601562 16.5 15 17.398438 15 18.300781 L 15 20.898438 C 15 21.199219 15.300781 21.5 15.699219 21.398438 C 19.398438 19.898438 22 16.300781 22 12.101562 C 22 6.101562 16.898438 1.398438 10.898438 2.101562 Z M 10.898438 2.101562 "/>
</g>
</svg>

      </a>
            
    
      
      <a href="https://www.jianshu.com/u/651a6ee53f49" title="jianshu" aria-label="jianshu">
        <svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32"><path fill="currentColor" d="M 6.8886719 1 C 6.4046719 1 6.0053906 1.3483125 5.9003906 1.8203125 C 5.6373906 2.9983125 4.7908438 5.0488437 2.5898438 6.0898438 C 2.2388438 6.2558437 2 6.5914688 2 6.9804688 L 2 7.0253906 C 2 7.6933906 2.6699687 8.1785 3.2929688 7.9375 C 3.7418759 7.7640455 4.1405134 7.5528964 4.5117188 7.3242188 A 1.0001 1.0001 0 0 0 4.7910156 8.2363281 C 4.7910156 8.2363281 5 8.3770193 5 9 A 1.0001 1.0001 0 1 0 7 9 C 7 7.6889807 6.2109375 6.8261719 6.2109375 6.8261719 A 1.0001 1.0001 0 0 0 5.5605469 6.5253906 C 6.0753568 6.0530628 6.4913817 5.5365138 6.8203125 5 L 7.3105469 5 C 7.623843 5.4287314 7.8943972 5.9150433 8.0332031 6.3222656 C 8.1712031 6.7272656 8.5554219 6.9921875 8.9824219 6.9921875 C 9.6734219 6.9921875 10.152453 6.3171562 9.9394531 5.6601562 C 9.869187 5.442609 9.7517566 5.2213533 9.6210938 5 L 11 5 C 11.552 5 12 4.552 12 4 C 12 3.448 11.552 3 11 3 L 7.703125 3 C 7.7849123 2.711735 7.8509558 2.4314303 7.8964844 2.1699219 C 8.0024844 1.5569219 7.5223906 1 6.9003906 1 L 6.8886719 1 z M 16.888672 1 C 16.404672 1 16.005391 1.3483125 15.900391 1.8203125 C 15.638391 2.9983125 14.790844 5.0488437 12.589844 6.0898438 C 12.238844 6.2558437 12 6.5914688 12 6.9804688 L 12 7.0253906 C 12 7.6933906 12.669969 8.1785 13.292969 7.9375 C 14.996474 7.2792779 16.101927 6.1717473 16.820312 5 L 17.310547 5 C 17.623843 5.4287314 17.894397 5.9150433 18.033203 6.3222656 C 18.171203 6.7272656 18.555422 6.9921875 18.982422 6.9921875 C 19.673422 6.9921875 20.152453 6.3171562 19.939453 5.6601562 C 19.869187 5.442609 19.751757 5.2213533 19.621094 5 L 21 5 C 21.552 5 22 4.552 22 4 C 22 3.448 21.552 3 21 3 L 17.703125 3 C 17.784912 2.711735 17.850956 2.4314303 17.896484 2.1699219 C 18.002484 1.5569219 17.522391 1 16.900391 1 L 16.888672 1 z M 9 8 A 1.0001 1.0001 0 1 0 9 10 L 18 10 L 18 19 C 18 19.56503 17.56503 20 17 20 L 16 20 A 1.0001 1.0001 0 1 0 16 22 L 17 22 C 18.64497 22 20 20.64497 20 19 L 20 9 A 1.0001 1.0001 0 0 0 19 8 L 9 8 z M 4.984375 10.986328 A 1.0001 1.0001 0 0 0 4 12 L 4 21 A 1.0001 1.0001 0 1 0 6 21 L 6 12 A 1.0001 1.0001 0 0 0 4.984375 10.986328 z M 9 12 A 1.0001 1.0001 0 0 0 8 13 L 8 19 A 1.0001 1.0001 0 0 0 9 20 L 13 20 C 14.64497 20 16 18.64497 16 17 L 16 16.167969 A 1.0001 1.0001 0 0 0 16 15.841797 L 16 13 A 1.0001 1.0001 0 0 0 15 12 L 9 12 z M 10 14 L 14 14 L 14 15 L 10 15 L 10 14 z M 10 17 L 14 17 C 14 17.56503 13.56503 18 13 18 L 10 18 L 10 17 z"/></svg>
      </a>
            
    
      
      <a href="tel:12345678900" title="phone" aria-label="phone">
        <svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32"><path fill="currentColor" d="M 8.65625 3 C 8.132813 3 7.617188 3.1875 7.1875 3.53125 L 7.125 3.5625 L 7.09375 3.59375 L 3.96875 6.8125 L 4 6.84375 C 3.035156 7.734375 2.738281 9.066406 3.15625 10.21875 C 3.160156 10.226563 3.152344 10.242188 3.15625 10.25 C 4.003906 12.675781 6.171875 17.359375 10.40625 21.59375 C 14.65625 25.84375 19.402344 27.925781 21.75 28.84375 L 21.78125 28.84375 C 22.996094 29.25 24.3125 28.960938 25.25 28.15625 L 28.40625 25 C 29.234375 24.171875 29.234375 22.734375 28.40625 21.90625 L 24.34375 17.84375 L 24.3125 17.78125 C 23.484375 16.953125 22.015625 16.953125 21.1875 17.78125 L 19.1875 19.78125 C 18.464844 19.433594 16.742188 18.542969 15.09375 16.96875 C 13.457031 15.40625 12.621094 13.609375 12.3125 12.90625 L 14.3125 10.90625 C 15.152344 10.066406 15.167969 8.667969 14.28125 7.84375 L 14.3125 7.8125 L 14.21875 7.71875 L 10.21875 3.59375 L 10.1875 3.5625 L 10.125 3.53125 C 9.695313 3.1875 9.179688 3 8.65625 3 Z M 8.65625 5 C 8.730469 5 8.804688 5.035156 8.875 5.09375 L 12.875 9.1875 L 12.96875 9.28125 C 12.960938 9.273438 13.027344 9.378906 12.90625 9.5 L 10.40625 12 L 9.9375 12.4375 L 10.15625 13.0625 C 10.15625 13.0625 11.304688 16.136719 13.71875 18.4375 L 13.9375 18.625 C 16.261719 20.746094 19 21.90625 19 21.90625 L 19.625 22.1875 L 22.59375 19.21875 C 22.765625 19.046875 22.734375 19.046875 22.90625 19.21875 L 27 23.3125 C 27.171875 23.484375 27.171875 23.421875 27 23.59375 L 23.9375 26.65625 C 23.476563 27.050781 22.988281 27.132813 22.40625 26.9375 C 20.140625 26.046875 15.738281 24.113281 11.8125 20.1875 C 7.855469 16.230469 5.789063 11.742188 5.03125 9.5625 C 4.878906 9.15625 4.988281 8.554688 5.34375 8.25 L 5.40625 8.1875 L 8.4375 5.09375 C 8.507813 5.035156 8.582031 5 8.65625 5 Z"/></svg>
      </a>
            
    
      
      <a href="https://steamcommunity.com/id/enternity33/" title="steam" aria-label="steam">
        <svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="32" height="32"><path fill="currentColor" d="M 25 3 C 13.59 3 4.209375 11.680781 3.109375 22.800781 L 14.300781 28.529297 C 15.430781 27.579297 16.9 27 18.5 27 L 18.550781 27 C 18.940781 26.4 19.389375 25.649141 19.859375 24.869141 C 20.839375 23.259141 21.939531 21.439062 23.019531 20.039062 C 23.259531 15.569063 26.97 12 31.5 12 C 36.19 12 40 15.81 40 20.5 C 40 25.03 36.430937 28.740469 31.960938 28.980469 C 30.560938 30.060469 28.750859 31.160859 27.130859 32.130859 C 26.350859 32.610859 25.6 33.059219 25 33.449219 L 25 33.5 C 25 37.09 22.09 40 18.5 40 C 14.91 40 12 37.09 12 33.5 C 12 33.33 12.009531 33.17 12.019531 33 L 3.2792969 28.519531 C 4.9692969 38.999531 14.05 47 25 47 C 37.15 47 47 37.15 47 25 C 47 12.85 37.15 3 25 3 z M 31.5 14 C 27.92 14 25 16.92 25 20.5 C 25 24.08 27.92 27 31.5 27 C 35.08 27 38 24.08 38 20.5 C 38 16.92 35.08 14 31.5 14 z M 31.5 16 C 33.99 16 36 18.01 36 20.5 C 36 22.99 33.99 25 31.5 25 C 29.01 25 27 22.99 27 20.5 C 27 18.01 29.01 16 31.5 16 z M 18.5 29 C 17.71 29 16.960313 29.200312 16.320312 29.570312 L 19.640625 31.269531 C 20.870625 31.899531 21.350469 33.410625 20.730469 34.640625 C 20.280469 35.500625 19.41 36 18.5 36 C 18.11 36 17.729375 35.910469 17.359375 35.730469 L 14.029297 34.019531 C 14.289297 36.259531 16.19 38 18.5 38 C 20.99 38 23 35.99 23 33.5 C 23 31.01 20.99 29 18.5 29 z"/></svg>
      </a>
            
    
            
    
      
      <a href="https://www.zhihu.com/people/vigilr" title="zhihu" aria-label="zhihu">
        <svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32"><path fill="currentColor" d="M 5.921875 2.9511719 C 5.5336094 2.9815469 5.1832344 3.2390625 5.0527344 3.6328125 L 3.6835938 7.7363281 C 3.5085938 8.2593281 3.7924062 8.825 4.3164062 9 C 4.8404063 9.175 5.4050781 8.8911875 5.5800781 8.3671875 L 6.0351562 7 L 6.9941406 7 L 6.9941406 10.222656 C 6.9941406 10.845846 6.9644144 11.431442 6.9199219 12 L 5 12 A 1.0001 1.0001 0 1 0 5 14 L 6.6367188 14 C 6.1575971 16.260332 5.1601574 17.989071 3.4179688 19.189453 C 2.9979688 19.479453 2.8798125 20.049188 3.1328125 20.492188 C 3.4258125 21.004188 4.0960781 21.153359 4.5800781 20.818359 C 6.0994455 19.769009 7.1700075 18.397613 7.8808594 16.720703 A 1.0001 1.0001 0 0 0 8.0449219 17.601562 L 9.5117188 19.59375 A 1.0002375 1.0002375 0 1 0 11.123047 18.408203 L 9.65625 16.416016 A 1.0001 1.0001 0 0 0 8.7929688 15.998047 A 1.0001 1.0001 0 0 0 7.9921875 16.472656 C 8.2917972 15.713486 8.5082238 14.883111 8.6699219 14 L 10 14 A 1.0001 1.0001 0 1 0 10 12 L 8.9316406 12 C 8.9726972 11.4285 8.9941406 10.836947 8.9941406 10.222656 L 8.9941406 7 L 10 7 A 1.0001 1.0001 0 1 0 10 5 L 6.7011719 5 L 6.9472656 4.2636719 C 7.1222656 3.7406719 6.8404063 3.175 6.3164062 3 C 6.1856563 2.95625 6.0512969 2.9410469 5.921875 2.9511719 z M 14 5 A 1.0001 1.0001 0 0 0 13 6 L 13 17 A 1.0001 1.0001 0 0 0 14 18 L 15 18 L 15 20 A 1.0001 1.0001 0 0 0 16.707031 20.707031 L 19.414062 18 L 21 18 A 1.0001 1.0001 0 0 0 22 17 L 22 6 A 1.0001 1.0001 0 0 0 21 5 L 14 5 z M 15 7 L 20 7 L 20 16 L 19 16 A 1.0001 1.0001 0 0 0 18.292969 16.292969 L 17 17.585938 L 17 17 A 1.0001 1.0001 0 0 0 16 16 L 15 16 L 15 7 z"/></svg>
      </a>
            
    
    
  
  
    
      <a href="https://eternidad33.gitee.io/zh/posts//index.xml" type="application/rss+xml" title="RSS" aria-label="RSS Feed Link">
        <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><circle fill="currentColor" cx="6.18" cy="17.82" r="2.18"/><path fill="currentColor" d="M5.59 10.23c-.84-.14-1.59.55-1.59 1.4 0 .71.53 1.28 1.23 1.4 2.92.51 5.22 2.82 5.74 5.74.12.7.69 1.23 1.4 1.23.85 0 1.54-.75 1.41-1.59-.68-4.2-3.99-7.51-8.19-8.18zm-.03-5.71C4.73 4.43 4 5.1 4 5.93c0 .73.55 1.33 1.27 1.4 6.01.6 10.79 5.38 11.39 11.39.07.73.67 1.28 1.4 1.28.84 0 1.5-.73 1.42-1.56-.73-7.34-6.57-13.19-13.92-13.92z"/></svg>
      </a>
    
  

  </div>
</div>

    
<div id="gtt">
  <div class="gtt">
    <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M8.12 14.71L12 10.83l3.88 3.88c.39.39 1.02.39 1.41 0 .39-.39.39-1.02 0-1.41L12.7 8.71c-.39-.39-1.02-.39-1.41 0L6.7 13.3c-.39.39-.39 1.02 0 1.41.39.38 1.03.39 1.42 0z"/></svg>
  </div>
</div>

    <hr />

    <div class="basicflex">
        
            <a href="" class="footer__link" target="_blank" rel="noreferrer"></a>
        
            <a href="" class="footer__link" target="_blank" rel="noreferrer"></a>
        
    </div>

    <div class="footer__poweredby">
        
                
            <p class="caption">
                
                    ©2021, All Rights Reserved
                
            </p>
        

        
            <p class="caption">Powered by <a href="https://gohugo.io/" target="_blank" rel="noreferrer">Hugo</a> and the <a href="https://github.com/zzossig/hugo-theme-zzo" target="_blank" rel="noreferrer">Zzo theme</a></p>
        
        
    </div> 
</footer>
        </div>
        





<div class="wrapper__right hide" data-pad="true" dir="ltr">
  <script>document.querySelector('.wrapper__right').classList.remove('hide')</script>
  
</div>

    </div>
</body>

</html>